slack-ruby-client 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +3 -0
  4. data/.rubocop_todo.yml +40 -39
  5. data/.travis.yml +1 -9
  6. data/CHANGELOG.md +24 -0
  7. data/CONTRIBUTING.md +2 -2
  8. data/Gemfile +3 -1
  9. data/README.md +40 -12
  10. data/Rakefile +1 -1
  11. data/UPGRADING.md +1 -1
  12. data/bin/commands/api.rb +2 -2
  13. data/bin/commands/apps_permissions.rb +22 -0
  14. data/bin/commands/auth.rb +4 -4
  15. data/bin/commands/bots.rb +2 -2
  16. data/bin/commands/channels.rb +52 -40
  17. data/bin/commands/chat.rb +63 -25
  18. data/bin/commands/conversations.rb +178 -0
  19. data/bin/commands/dialog.rb +14 -0
  20. data/bin/commands/dnd.rb +8 -8
  21. data/bin/commands/emoji.rb +2 -2
  22. data/bin/commands/files.rb +38 -17
  23. data/bin/commands/files_comments.rb +6 -6
  24. data/bin/commands/groups.rb +44 -51
  25. data/bin/commands/im.rb +16 -13
  26. data/bin/commands/migration.rb +14 -0
  27. data/bin/commands/mpim.rb +11 -11
  28. data/bin/commands/oauth.rb +15 -2
  29. data/bin/commands/pins.rb +6 -6
  30. data/bin/commands/reactions.rb +13 -13
  31. data/bin/commands/reminders.rb +10 -10
  32. data/bin/commands/rtm.rb +9 -6
  33. data/bin/commands/search.rb +9 -9
  34. data/bin/commands/stars.rb +8 -8
  35. data/bin/commands/team.rb +10 -10
  36. data/bin/commands/team_profile.rb +2 -2
  37. data/bin/commands/usergroups.rb +16 -16
  38. data/bin/commands/usergroups_users.rb +4 -4
  39. data/bin/commands/users.rb +40 -36
  40. data/bin/commands/users_admin.rb +28 -0
  41. data/bin/commands/users_prefs.rb +12 -0
  42. data/bin/commands/users_profile.rb +7 -7
  43. data/bin/commands.rb +7 -1
  44. data/bin/slack +1 -1
  45. data/examples/hi_real_time/hi.rb +1 -1
  46. data/examples/hi_real_time_and_web/hi.rb +1 -1
  47. data/examples/hi_real_time_async_celluloid/hi.rb +1 -1
  48. data/examples/hi_real_time_async_eventmachine/hi.rb +1 -1
  49. data/examples/hi_web/hi.rb +1 -1
  50. data/examples/new_ticket/new_ticket.rb +1 -1
  51. data/lib/slack/messages/formatting.rb +4 -4
  52. data/lib/slack/messages/message.rb +1 -2
  53. data/lib/slack/real_time/api/templates/event_handler.erb +1 -1
  54. data/lib/slack/real_time/client.rb +11 -10
  55. data/lib/slack/real_time/concurrency/celluloid.rb +6 -2
  56. data/lib/slack/real_time/config.rb +11 -11
  57. data/lib/slack/real_time/models/base.rb +1 -2
  58. data/lib/slack/real_time/socket.rb +2 -2
  59. data/lib/slack/real_time/stores/base.rb +1 -2
  60. data/lib/slack/real_time/stores/starter.rb +92 -72
  61. data/lib/slack/real_time/stores/store.rb +120 -90
  62. data/lib/slack/version.rb +1 -1
  63. data/lib/slack/web/api/endpoints/api.rb +2 -2
  64. data/lib/slack/web/api/endpoints/apps_permissions.rb +35 -0
  65. data/lib/slack/web/api/endpoints/auth.rb +4 -4
  66. data/lib/slack/web/api/endpoints/bots.rb +2 -2
  67. data/lib/slack/web/api/endpoints/channels.rb +57 -34
  68. data/lib/slack/web/api/endpoints/chat.rb +107 -37
  69. data/lib/slack/web/api/endpoints/conversations.rb +301 -0
  70. data/lib/slack/web/api/endpoints/dialog.rb +32 -0
  71. data/lib/slack/web/api/endpoints/dnd.rb +9 -9
  72. data/lib/slack/web/api/endpoints/emoji.rb +2 -2
  73. data/lib/slack/web/api/endpoints/files.rb +53 -23
  74. data/lib/slack/web/api/endpoints/files_comments.rb +11 -11
  75. data/lib/slack/web/api/endpoints/groups.rb +38 -50
  76. data/lib/slack/web/api/endpoints/im.rb +27 -17
  77. data/lib/slack/web/api/endpoints/migration.rb +25 -0
  78. data/lib/slack/web/api/endpoints/mpim.rb +13 -15
  79. data/lib/slack/web/api/endpoints/oauth.rb +24 -3
  80. data/lib/slack/web/api/endpoints/pins.rb +6 -8
  81. data/lib/slack/web/api/endpoints/presence.rb +1 -1
  82. data/lib/slack/web/api/endpoints/reactions.rb +18 -20
  83. data/lib/slack/web/api/endpoints/reminders.rb +10 -10
  84. data/lib/slack/web/api/endpoints/rtm.rb +14 -8
  85. data/lib/slack/web/api/endpoints/search.rb +12 -12
  86. data/lib/slack/web/api/endpoints/stars.rb +10 -12
  87. data/lib/slack/web/api/endpoints/team.rb +12 -13
  88. data/lib/slack/web/api/endpoints/team_profile.rb +2 -2
  89. data/lib/slack/web/api/endpoints/usergroups.rb +22 -22
  90. data/lib/slack/web/api/endpoints/usergroups_users.rb +4 -4
  91. data/lib/slack/web/api/endpoints/users.rb +34 -24
  92. data/lib/slack/web/api/endpoints/users_admin.rb +46 -0
  93. data/lib/slack/web/api/endpoints/users_prefs.rb +19 -0
  94. data/lib/slack/web/api/endpoints/users_profile.rb +10 -10
  95. data/lib/slack/web/api/endpoints.rb +14 -2
  96. data/lib/slack/web/api/mixins/ids.id.rb +1 -1
  97. data/lib/slack/web/api/mixins/users.search.rb +38 -36
  98. data/lib/slack/web/api/patches/chat.1.text-attachments-required.patch +1 -1
  99. data/lib/slack/web/api/patches/chat.3.update-attachments-support.patch +4 -3
  100. data/lib/slack/web/api/patches/chat.4.postEphemeral-attachments-support.patch +17 -0
  101. data/lib/slack/web/api/patches/dialog.1.open-json-support.patch +17 -0
  102. data/lib/slack/web/api/templates/command.erb +4 -3
  103. data/lib/slack/web/api/templates/commands.erb +1 -1
  104. data/lib/slack/web/api/templates/endpoints.erb +2 -2
  105. data/lib/slack/web/api/templates/method.erb +18 -3
  106. data/lib/slack/web/api/templates/method_spec.erb +1 -1
  107. data/lib/slack/web/config.rb +16 -12
  108. data/lib/slack/web/faraday/connection.rb +1 -1
  109. data/lib/slack/web/faraday/response/raise_error.rb +3 -3
  110. data/lib/slack/web/pagination/cursor.rb +48 -0
  111. data/lib/slack-ruby-client.rb +6 -0
  112. data/lib/tasks/git.rake +1 -1
  113. data/lib/tasks/real_time.rake +1 -1
  114. data/lib/tasks/web.rake +4 -1
  115. data/slack-ruby-client.gemspec +2 -3
  116. data/spec/fixtures/slack/web/paginated_users_list.yml +181 -0
  117. data/spec/integration/integration_spec.rb +1 -1
  118. data/spec/slack/messages/formatting_spec.rb +1 -1
  119. data/spec/slack/real_time/client_spec.rb +62 -63
  120. data/spec/slack/real_time/concurrency/celluloid_spec.rb +41 -31
  121. data/spec/slack/real_time/concurrency/it_behaves_like_a_realtime_socket.rb +1 -1
  122. data/spec/slack/real_time/event_handlers/bot_spec.rb +4 -2
  123. data/spec/slack/real_time/event_handlers/event_handlers_spec.rb +1 -1
  124. data/spec/slack/real_time/event_handlers/user_spec.rb +4 -2
  125. data/spec/slack/web/api/endpoints/apps_permissions_spec.rb +15 -0
  126. data/spec/slack/web/api/endpoints/conversations_spec.rb +100 -0
  127. data/spec/slack/web/api/endpoints/custom_specs/chat_spec.rb +37 -1
  128. data/spec/slack/web/api/endpoints/custom_specs/dialog_spec.rb +28 -0
  129. data/spec/slack/web/api/endpoints/custom_specs/users_spec.rb +16 -6
  130. data/spec/slack/web/api/endpoints/files_comments_spec.rb +8 -8
  131. data/spec/slack/web/api/endpoints/files_spec.rb +16 -5
  132. data/spec/slack/web/api/endpoints/migration_spec.rb +12 -0
  133. data/spec/slack/web/api/endpoints/oauth_spec.rb +11 -0
  134. data/spec/slack/web/api/endpoints/users_admin_spec.rb +17 -0
  135. data/spec/slack/web/api/endpoints/users_prefs_spec.rb +7 -0
  136. data/spec/slack/web/api/error_spec.rb +1 -1
  137. data/spec/slack/web/api/errors/slack_error_spec.rb +1 -1
  138. data/spec/slack/web/api/mixins/users_spec.rb +6 -4
  139. data/spec/slack/web/api/pagination/cursor_spec.rb +70 -0
  140. data/spec/support/queue_with_timeout.rb +1 -1
  141. data/spec/support/real_time/concurrency/mock.rb +1 -2
  142. metadata +47 -30
@@ -0,0 +1,48 @@
1
+ module Slack
2
+ module Web
3
+ module Api
4
+ module Pagination
5
+ class Cursor
6
+ include Enumerable
7
+
8
+ attr_reader :client
9
+ attr_reader :verb
10
+ attr_reader :sleep_interval
11
+ attr_reader :max_retries
12
+ attr_reader :params
13
+
14
+ def initialize(client, verb, params = {})
15
+ @client = client
16
+ @verb = verb
17
+ @params = params.dup
18
+ @sleep_interval = @params.delete(:sleep_interval)
19
+ @max_retries = @params.delete(:max_retries) || client.default_max_retries
20
+ end
21
+
22
+ def each
23
+ next_cursor = nil
24
+ retry_count = 0
25
+ loop do
26
+ query = { limit: client.default_page_size }.merge(params).merge(cursor: next_cursor)
27
+ begin
28
+ response = client.send(verb, query)
29
+ rescue Slack::Web::Api::Errors::TooManyRequestsError => e
30
+ raise e if retry_count >= max_retries
31
+ client.logger.debug("#{self.class}##{__method__}") { e.to_s }
32
+ retry_count += 1
33
+ sleep(e.retry_after.seconds)
34
+ next
35
+ end
36
+ yield response
37
+ break unless response.response_metadata
38
+ next_cursor = response.response_metadata.next_cursor
39
+ break if next_cursor.blank?
40
+ retry_count = 0
41
+ sleep(sleep_interval) if sleep_interval
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -17,6 +17,11 @@ begin
17
17
  rescue LoadError
18
18
  # ignore, only used in users_search
19
19
  end
20
+ begin
21
+ require 'openssl'
22
+ rescue LoadError
23
+ # Used in slack/web/config
24
+ end
20
25
  require_relative 'slack/web/config'
21
26
  require_relative 'slack/web/api/errors/slack_error'
22
27
  require_relative 'slack/web/api/errors/too_many_requests_error'
@@ -26,6 +31,7 @@ require_relative 'slack/web/faraday/connection'
26
31
  require_relative 'slack/web/faraday/request'
27
32
  require_relative 'slack/web/api/mixins'
28
33
  require_relative 'slack/web/api/endpoints'
34
+ require_relative 'slack/web/pagination/cursor'
29
35
  require_relative 'slack/web/client'
30
36
 
31
37
  # RealTime API
data/lib/tasks/git.rake CHANGED
@@ -1,5 +1,5 @@
1
1
  namespace :slack do
2
- # update slack-api-ref from https://github.com/dblock/slack-api-ref
2
+ # update slack-api-ref from https://github.com/slack-ruby/slack-api-ref
3
3
  task :git_update do
4
4
  sh 'git submodule update --init --recursive'
5
5
  sh 'git submodule foreach git pull origin master'
@@ -14,7 +14,7 @@ namespace :slack do
14
14
  name = File.basename(path, '.json')
15
15
  parsed = JSON.parse(File.read(path))
16
16
  JSON::Validator.validate(event_schema, parsed, insert_defaults: true)
17
- next if %w(message hello).include?(name)
17
+ next if %w[message hello].include?(name)
18
18
  result[name] = parsed
19
19
  end
20
20
 
data/lib/tasks/web.rake CHANGED
@@ -13,6 +13,7 @@ namespace :slack do
13
13
  groups = Dir.glob('lib/slack/web/api/slack-api-ref/groups/**/*.json').each_with_object({}) do |path, result|
14
14
  name = File.basename(path, '.json')
15
15
  parsed = JSON.parse(File.read(path))
16
+ parsed['undocumented'] = true if path =~ /undocumented/
16
17
  JSON::Validator.validate(group_schema, parsed, insert_defaults: true)
17
18
  result[name] = parsed
18
19
  end
@@ -27,6 +28,7 @@ namespace :slack do
27
28
  name = file_name.split('.')[-1]
28
29
  result[prefix] ||= {}
29
30
  parsed = JSON.parse(File.read(path))
31
+ parsed['undocumented'] = true if path =~ /undocumented/
30
32
  JSON::Validator.validate(method_schema, parsed, insert_defaults: true)
31
33
  result[prefix][name] = parsed
32
34
  end
@@ -47,9 +49,10 @@ namespace :slack do
47
49
  end
48
50
  Dir.glob("lib/slack/web/api/patches/#{group}*.patch").sort.each do |patch|
49
51
  puts "- patching #{patch}"
50
- system("git apply #{patch}") || fail('failed to apply patch')
52
+ system("git apply #{patch}") || raise('failed to apply patch')
51
53
  end
52
54
  # command
55
+ raise "Missing group #{group}" unless groups.key?(group)
53
56
  rendered_command = command_template.result(group: groups[group], names: names)
54
57
  File.write "bin/commands/#{snaked_group}.rb", rendered_command
55
58
  end
@@ -19,15 +19,14 @@ Gem::Specification.new do |s|
19
19
  s.add_dependency 'activesupport'
20
20
  s.add_dependency 'faraday', '>= 0.9'
21
21
  s.add_dependency 'faraday_middleware'
22
- s.add_dependency 'json'
23
- s.add_dependency 'websocket-driver'
24
22
  s.add_dependency 'gli'
25
23
  s.add_dependency 'hashie'
24
+ s.add_dependency 'websocket-driver'
26
25
  s.add_development_dependency 'erubis'
27
26
  s.add_development_dependency 'json-schema'
28
27
  s.add_development_dependency 'rake', '~> 10'
29
28
  s.add_development_dependency 'rspec'
29
+ s.add_development_dependency 'rubocop', '0.51.0'
30
30
  s.add_development_dependency 'vcr'
31
31
  s.add_development_dependency 'webmock'
32
- s.add_development_dependency 'rubocop', '0.35.0'
33
32
  end
@@ -0,0 +1,181 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://slack.com/api/users.list
6
+ body:
7
+ encoding: UTF-8
8
+ string: limit=5&presence=true&token=token
9
+ headers:
10
+ Accept:
11
+ - application/json; charset=utf-8
12
+ User-Agent:
13
+ - Slack Ruby Client/0.9.2
14
+ Content-Type:
15
+ - application/x-www-form-urlencoded
16
+ Accept-Encoding:
17
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Content-Type:
24
+ - application/json; charset=utf-8
25
+ body:
26
+ encoding: ASCII-8BIT
27
+ string: '{"ok":true,"offset":"U07518DTL","members":[{"id":"USLACKBOT","team_id":"T04KB5WQH","name":"slackbot","deleted":false,"color":"757575","real_name":"slackbot","tz":null,"tz_label":"Pacific
28
+ Daylight Time","tz_offset":-25200,"profile":{"first_name":"slackbot","last_name":"","image_24":"https:\/\/a.slack-edge.com\/0180\/img\/slackbot_24.png","image_32":"https:\/\/a.slack-edge.com\/2fac\/plugins\/slackbot\/assets\/service_32.png","image_48":"https:\/\/a.slack-edge.com\/2fac\/plugins\/slackbot\/assets\/service_48.png","image_72":"https:\/\/a.slack-edge.com\/0180\/img\/slackbot_72.png","image_192":"https:\/\/a.slack-edge.com\/66f9\/img\/slackbot_192.png","image_512":"https:\/\/a.slack-edge.com\/1801\/img\/slackbot_512.png","avatar_hash":"sv1444671949","always_active":true,"real_name":"slackbot","real_name_normalized":"slackbot","fields":null,"team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"updated":0,"is_app_user":false},{"id":"U04JPQ0JS","team_id":"T04KB5WQH","name":"gamebot","deleted":true,"profile":{"bot_id":"B04JPQ0JE","image_24":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4635825662_28d3661bf00dc6013442_24.jpg","image_32":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4635825662_28d3661bf00dc6013442_32.jpg","image_48":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4635825662_28d3661bf00dc6013442_48.jpg","image_72":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4635825662_28d3661bf00dc6013442_48.jpg","image_192":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4635825662_28d3661bf00dc6013442_48.jpg","image_original":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4635825662_28d3661bf00dc6013442_original.jpg","first_name":"Game","last_name":"Bot","title":"Game
29
+ ons.","avatar_hash":"28d3661bf00d","real_name":"Game Bot","real_name_normalized":"Game
30
+ Bot","team":"T04KB5WQH"},"is_bot":true,"updated":1459895593,"is_app_user":false,"presence":"away"},{"id":"U04JZBDQQ","team_id":"T04KB5WQH","name":"foo","deleted":true,"profile":{"bot_id":"B04JZBDQC","image_24":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4645387956_44604ca32e800d947f22_24.jpg","image_32":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4645387956_44604ca32e800d947f22_32.jpg","image_48":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4645387956_44604ca32e800d947f22_48.jpg","image_72":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4645387956_44604ca32e800d947f22_72.jpg","image_192":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4645387956_44604ca32e800d947f22_192.jpg","image_original":"https:\/\/avatars.slack-edge.com\/2015-04-28\/4645387956_44604ca32e800d947f22_original.jpg","avatar_hash":"44604ca32e80","real_name":"","real_name_normalized":"","team":"T04KB5WQH"},"is_bot":true,"updated":1459895600,"is_app_user":false,"presence":"away"},{"id":"U04KB5WQR","team_id":"T04KB5WQH","name":"dblock","deleted":false,"color":"9f69e7","real_name":"Daniel","tz":"America\/Indiana\/Indianapolis","tz_label":"Eastern
31
+ Daylight Time","tz_offset":-14400,"profile":{"first_name":"Daniel","last_name":"","title":"","phone":"","skype":"","avatar_hash":"g3d925b45ac0","real_name":"Daniel","real_name_normalized":"Daniel","email":"dblock@example.com","image_24":"https:\/\/secure.gravatar.com\/avatar\/3d925b45ac07ec0ae5bd04888f6c5b61.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0015-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/3d925b45ac07ec0ae5bd04888f6c5b61.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0015-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/3d925b45ac07ec0ae5bd04888f6c5b61.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0015-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/3d925b45ac07ec0ae5bd04888f6c5b61.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0015-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/3d925b45ac07ec0ae5bd04888f6c5b61.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0015-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/3d925b45ac07ec0ae5bd04888f6c5b61.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0015-512.png","team":"T04KB5WQH"},"is_admin":true,"is_owner":true,"is_primary_owner":true,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"updated":1459895609,"is_app_user":false,"presence":"active"},{"id":"U06JGTU5V","team_id":"T04KB5WQH","name":"mathbot","deleted":true,"profile":{"bot_id":"B06JH1N93","image_24":"https:\/\/avatars.slack-edge.com\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_24.jpg","image_32":"https:\/\/avatars.slack-edge.com\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_32.jpg","image_48":"https:\/\/avatars.slack-edge.com\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_48.jpg","image_72":"https:\/\/avatars.slack-edge.com\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_48.jpg","image_192":"https:\/\/avatars.slack-edge.com\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_48.jpg","image_original":"https:\/\/avatars.slack-edge.com\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_original.jpg","first_name":"Math","last_name":"Bot","avatar_hash":"c507c80d735d","real_name":"Math
32
+ Bot","real_name_normalized":"Math Bot","team":"T04KB5WQH"},"is_bot":true,"updated":1459895914,"is_app_user":false,"presence":"away"}],"cache_ts":1504041966,"response_metadata":{"next_cursor":"dXNlcjpVMDc1MThEVEw="}}'
33
+ http_version:
34
+ recorded_at: Tue, 29 Aug 2017 21:26:06 GMT
35
+ - request:
36
+ method: post
37
+ uri: https://slack.com/api/users.list
38
+ body:
39
+ encoding: UTF-8
40
+ string: cursor=dXNlcjpVMDc1MThEVEw%3D&limit=5&presence=true&token=token
41
+ headers:
42
+ Accept:
43
+ - application/json; charset=utf-8
44
+ User-Agent:
45
+ - Slack Ruby Client/0.9.2
46
+ Content-Type:
47
+ - application/x-www-form-urlencoded
48
+ Accept-Encoding:
49
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
50
+ response:
51
+ status:
52
+ code: 200
53
+ message: OK
54
+ headers:
55
+ Content-Type:
56
+ - application/json; charset=utf-8
57
+ body:
58
+ encoding: ASCII-8BIT
59
+ string: '{"ok":true,"offset":"U0GPR6KDJ","members":[{"id":"U07518DTL","team_id":"T04KB5WQH","name":"testbot","deleted":false,"color":"674b1b","real_name":"Art
60
+ Bot","tz":null,"tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"bot_id":"B0751JU2H","image_24":"https:\/\/avatars.slack-edge.com\/2015-07-02\/7171641589_359bf095c1fe0841e582_24.jpg","image_32":"https:\/\/avatars.slack-edge.com\/2015-07-02\/7171641589_359bf095c1fe0841e582_32.jpg","image_48":"https:\/\/avatars.slack-edge.com\/2015-07-02\/7171641589_359bf095c1fe0841e582_48.jpg","image_72":"https:\/\/avatars.slack-edge.com\/2015-07-02\/7171641589_359bf095c1fe0841e582_48.jpg","image_192":"https:\/\/avatars.slack-edge.com\/2015-07-02\/7171641589_359bf095c1fe0841e582_48.jpg","image_original":"https:\/\/avatars.slack-edge.com\/2015-07-02\/7171641589_359bf095c1fe0841e582_original.jpg","title":"Also
61
+ used in Travis-CI for slack-ruby-client.","avatar_hash":"359bf095c1fe","first_name":"Art","last_name":"Bot","real_name":"Art
62
+ Bot","real_name_normalized":"Art Bot","team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"updated":1464624441,"is_app_user":false,"presence":"away"},{"id":"U07KECJ77","team_id":"T04KB5WQH","name":"aws","deleted":true,"profile":{"bot_id":"B07KECJ6R","image_24":"https:\/\/avatars.slack-edge.com\/2015-07-14\/7660472085_4755a86e204c9706c84f_24.jpg","image_32":"https:\/\/avatars.slack-edge.com\/2015-07-14\/7660472085_4755a86e204c9706c84f_32.jpg","image_48":"https:\/\/avatars.slack-edge.com\/2015-07-14\/7660472085_4755a86e204c9706c84f_48.jpg","image_72":"https:\/\/avatars.slack-edge.com\/2015-07-14\/7660472085_4755a86e204c9706c84f_48.jpg","image_192":"https:\/\/avatars.slack-edge.com\/2015-07-14\/7660472085_4755a86e204c9706c84f_48.jpg","image_original":"https:\/\/avatars.slack-edge.com\/2015-07-14\/7660472085_4755a86e204c9706c84f_original.jpg","first_name":"AWS","last_name":"Cloud","avatar_hash":"4755a86e204c","real_name":"AWS
63
+ Cloud","real_name_normalized":"AWS Cloud","team":"T04KB5WQH"},"is_bot":true,"updated":1459895941,"is_app_user":false,"presence":"away"},{"id":"U092BDCLV","team_id":"T04KB5WQH","name":"artsy","deleted":true,"profile":{"bot_id":"B092B5DDG","image_24":"https:\/\/avatars.slack-edge.com\/2015-08-13\/9080316676_7bbab49314a0429c7f7d_24.jpg","image_32":"https:\/\/avatars.slack-edge.com\/2015-08-13\/9080316676_7bbab49314a0429c7f7d_32.jpg","image_48":"https:\/\/avatars.slack-edge.com\/2015-08-13\/9080316676_7bbab49314a0429c7f7d_48.jpg","image_72":"https:\/\/avatars.slack-edge.com\/2015-08-13\/9080316676_7bbab49314a0429c7f7d_48.jpg","image_192":"https:\/\/avatars.slack-edge.com\/2015-08-13\/9080316676_7bbab49314a0429c7f7d_48.jpg","image_512":"https:\/\/avatars.slack-edge.com\/2015-08-13\/9080316676_7bbab49314a0429c7f7d_48.jpg","image_1024":"https:\/\/avatars.slack-edge.com\/2015-08-13\/9080316676_7bbab49314a0429c7f7d_48.jpg","image_original":"https:\/\/avatars.slack-edge.com\/2015-08-13\/9080316676_7bbab49314a0429c7f7d_original.jpg","first_name":"Artsy","last_name":"Bot","title":"Searches
64
+ Artsy.","avatar_hash":"7bbab49314a0","real_name":"Artsy Bot","real_name_normalized":"Artsy
65
+ Bot","team":"T04KB5WQH"},"is_bot":true,"updated":1459895974,"is_app_user":false,"presence":"away"},{"id":"U092V4E9L","team_id":"T04KB5WQH","name":"broskoski","deleted":true,"profile":{"first_name":"Cab","avatar_hash":"g99621cbca6e","real_name":"Cab","real_name_normalized":"Cab","email":"cab@example.com","image_24":"https:\/\/secure.gravatar.com\/avatar\/99621cbca6ea94706a8f5dcdc5e8af4a.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F0180%2Fimg%2Favatars%2Fava_0017-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/99621cbca6ea94706a8f5dcdc5e8af4a.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0017-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/99621cbca6ea94706a8f5dcdc5e8af4a.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0017-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/99621cbca6ea94706a8f5dcdc5e8af4a.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0017-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/99621cbca6ea94706a8f5dcdc5e8af4a.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0017-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/99621cbca6ea94706a8f5dcdc5e8af4a.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0017-512.png","team":"T04KB5WQH"},"is_bot":false,"updated":1459895974,"is_app_user":false,"presence":"away"},{"id":"U0EA7TZJN","team_id":"T04KB5WQH","name":"bar","deleted":true,"profile":{"bot_id":"B0EA31LQM","image_24":"https:\/\/avatars.slack-edge.com\/2015-11-11\/14346833313_f359ba59a1211d17912b_24.jpg","image_32":"https:\/\/avatars.slack-edge.com\/2015-11-11\/14346833313_f359ba59a1211d17912b_32.jpg","image_48":"https:\/\/avatars.slack-edge.com\/2015-11-11\/14346833313_f359ba59a1211d17912b_48.jpg","image_72":"https:\/\/avatars.slack-edge.com\/2015-11-11\/14346833313_f359ba59a1211d17912b_72.jpg","image_192":"https:\/\/avatars.slack-edge.com\/2015-11-11\/14346833313_f359ba59a1211d17912b_192.jpg","image_512":"https:\/\/avatars.slack-edge.com\/2015-11-11\/14346833313_f359ba59a1211d17912b_512.jpg","image_1024":"https:\/\/avatars.slack-edge.com\/2015-11-11\/14346833313_f359ba59a1211d17912b_512.jpg","image_original":"https:\/\/avatars.slack-edge.com\/2015-11-11\/14346833313_f359ba59a1211d17912b_original.jpg","avatar_hash":"f359ba59a121","real_name":"","real_name_normalized":"","team":"T04KB5WQH"},"is_bot":true,"updated":1459896059,"is_app_user":false,"presence":"away"}],"cache_ts":1504042259,"response_metadata":{"next_cursor":"dXNlcjpVMEdQUjZLREo="}}'
66
+ http_version:
67
+ recorded_at: Tue, 29 Aug 2017 21:30:59 GMT
68
+ - request:
69
+ method: post
70
+ uri: https://slack.com/api/users.list
71
+ body:
72
+ encoding: UTF-8
73
+ string: cursor=dXNlcjpVMEdQUjZLREo%3D&limit=5&presence=true&token=token
74
+ headers:
75
+ Accept:
76
+ - application/json; charset=utf-8
77
+ User-Agent:
78
+ - Slack Ruby Client/0.9.2
79
+ Content-Type:
80
+ - application/x-www-form-urlencoded
81
+ Accept-Encoding:
82
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
83
+ response:
84
+ status:
85
+ code: 200
86
+ message: OK
87
+ headers:
88
+ Content-Type:
89
+ - application/json; charset=utf-8
90
+ body:
91
+ encoding: ASCII-8BIT
92
+ string: '{"ok":true,"offset":"U0HLFUZLJ","members":[{"id":"U0GPR6KDJ","team_id":"T04KB5WQH","name":"slackbotserver","deleted":false,"color":"2b6836","real_name":"slack-ruby-bot-server","tz":null,"tz_label":"Pacific
93
+ Daylight Time","tz_offset":-25200,"profile":{"first_name":"slack-ruby-bot-server","bot_id":"B0GPWQWHY","api_app_id":"A0GPRTG9Z","avatar_hash":"g36f3834829d","real_name":"slack-ruby-bot-server","real_name_normalized":"slack-ruby-bot-server","image_24":"https:\/\/secure.gravatar.com\/avatar\/36f3834829d1ec429f7d6acebccc7641.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0008-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/36f3834829d1ec429f7d6acebccc7641.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0008-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/36f3834829d1ec429f7d6acebccc7641.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0008-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/36f3834829d1ec429f7d6acebccc7641.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0008-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/36f3834829d1ec429f7d6acebccc7641.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0008-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/36f3834829d1ec429f7d6acebccc7641.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0008-512.png","team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"updated":1464900685,"is_app_user":false,"presence":"away"},{"id":"U0H15MV1R","team_id":"T04KB5WQH","name":"pongbot","deleted":false,"color":"99a949","real_name":"PlayPlay.io
94
+ - Ping-Pong for Slack","tz":null,"tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"first_name":"PlayPlay.io
95
+ - Ping-Pong for Slack","bot_id":"B0H184MLZ","api_app_id":"A0H0ZJHP0","avatar_hash":"bfc0baddb5a2","image_24":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52297978466_bfc0baddb5a2d42da036_24.png","image_32":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52297978466_bfc0baddb5a2d42da036_32.png","image_48":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52297978466_bfc0baddb5a2d42da036_48.png","image_72":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52297978466_bfc0baddb5a2d42da036_72.png","image_192":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52297978466_bfc0baddb5a2d42da036_192.png","image_512":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52297978466_bfc0baddb5a2d42da036_512.png","image_1024":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52297978466_bfc0baddb5a2d42da036_512.png","image_original":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52297978466_bfc0baddb5a2d42da036_original.png","real_name":"PlayPlay.io
96
+ - Ping-Pong for Slack","real_name_normalized":"PlayPlay.io - Ping-Pong for
97
+ Slack","team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"updated":1466351075,"is_app_user":false,"presence":"active"},{"id":"U0H701CJZ","team_id":"T04KB5WQH","name":"chessbot","deleted":false,"color":"df3dc0","real_name":"PlayPlay.io
98
+ - Chess for Slack","tz":null,"tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"first_name":"PlayPlay.io
99
+ - Chess for Slack","bot_id":"B0H74MK3J","api_app_id":"A0H70N5C3","avatar_hash":"8f99e84480d6","image_24":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52298008610_8f99e84480d6baed1771_24.png","image_32":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52298008610_8f99e84480d6baed1771_32.png","image_48":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52298008610_8f99e84480d6baed1771_48.png","image_72":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52298008610_8f99e84480d6baed1771_72.png","image_192":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52298008610_8f99e84480d6baed1771_192.png","image_512":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52298008610_8f99e84480d6baed1771_512.png","image_1024":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52298008610_8f99e84480d6baed1771_512.png","image_original":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52298008610_8f99e84480d6baed1771_original.png","real_name":"PlayPlay.io
100
+ - Chess for Slack","real_name_normalized":"PlayPlay.io - Chess for Slack","team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"updated":1466351099,"is_app_user":false,"presence":"away"},{"id":"U0HC7MSEA","team_id":"T04KB5WQH","name":"poolbot","deleted":false,"color":"4cc091","real_name":"PlayPlay.io
101
+ - Billiards for Slack","tz":null,"tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"first_name":"PlayPlay.io
102
+ - Billiards for Slack","bot_id":"B0HC7D1SN","api_app_id":"A0HC74EET","avatar_hash":"c95d3eeede11","image_24":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52283120304_c95d3eeede11f766a974_24.png","image_32":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52283120304_c95d3eeede11f766a974_32.png","image_48":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52283120304_c95d3eeede11f766a974_48.png","image_72":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52283120304_c95d3eeede11f766a974_72.png","image_192":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52283120304_c95d3eeede11f766a974_192.png","image_512":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52283120304_c95d3eeede11f766a974_512.png","image_1024":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52283120304_c95d3eeede11f766a974_512.png","image_original":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52283120304_c95d3eeede11f766a974_original.png","real_name":"PlayPlay.io
103
+ - Billiards for Slack","real_name_normalized":"PlayPlay.io - Billiards for
104
+ Slack","team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"updated":1466351115,"is_app_user":false,"presence":"away"},{"id":"U0HF43KT7","team_id":"T04KB5WQH","name":"tictactoe","deleted":false,"color":"9b3b45","real_name":"PlayPlay.io
105
+ - Tic-Tac-Toe for Slack","tz":null,"tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"first_name":"PlayPlay.io
106
+ - Tic-Tac-Toe for Slack","bot_id":"B0HF56491","api_app_id":"A0HF3E0AH","avatar_hash":"4a2b920dbea1","image_24":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52238814435_4a2b920dbea1335fd188_24.png","image_32":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52238814435_4a2b920dbea1335fd188_32.png","image_48":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52238814435_4a2b920dbea1335fd188_48.png","image_72":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52238814435_4a2b920dbea1335fd188_72.png","image_192":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52238814435_4a2b920dbea1335fd188_192.png","image_512":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52238814435_4a2b920dbea1335fd188_512.png","image_1024":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52238814435_4a2b920dbea1335fd188_512.png","image_original":"https:\/\/avatars.slack-edge.com\/2016-06-19\/52238814435_4a2b920dbea1335fd188_original.png","real_name":"PlayPlay.io
107
+ - Tic-Tac-Toe for Slack","real_name_normalized":"PlayPlay.io - Tic-Tac-Toe
108
+ for Slack","team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"updated":1466351125,"is_app_user":false,"presence":"away"}],"cache_ts":1504042259,"response_metadata":{"next_cursor":"dXNlcjpVMEhMRlVaTEo="}}'
109
+ http_version:
110
+ recorded_at: Tue, 29 Aug 2017 21:30:59 GMT
111
+ - request:
112
+ method: post
113
+ uri: https://slack.com/api/users.list
114
+ body:
115
+ encoding: UTF-8
116
+ string: cursor=dXNlcjpVMEhMRlVaTEo%3D&limit=5&presence=true&token=token
117
+ headers:
118
+ Accept:
119
+ - application/json; charset=utf-8
120
+ User-Agent:
121
+ - Slack Ruby Client/0.9.2
122
+ Content-Type:
123
+ - application/x-www-form-urlencoded
124
+ Accept-Encoding:
125
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
126
+ response:
127
+ status:
128
+ code: 200
129
+ message: OK
130
+ headers:
131
+ Content-Type:
132
+ - application/json; charset=utf-8
133
+ body:
134
+ encoding: ASCII-8BIT
135
+ string: '{"ok":true,"offset":"U0S0G028K","members":[{"id":"U0HLFUZLJ","team_id":"T04KB5WQH","name":"player1","deleted":false,"color":"d58247","real_name":"Player
136
+ 1","tz":"America\/Indiana\/Indianapolis","tz_label":"Eastern Daylight Time","tz_offset":-14400,"profile":{"first_name":"Player","last_name":"1","avatar_hash":"gcde4e113736","real_name":"Player
137
+ 1","real_name_normalized":"Player 1","email":"dblock+example.com.org","image_24":"https:\/\/secure.gravatar.com\/avatar\/cde4e1137364cf971f15160113b04e86.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0009-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/cde4e1137364cf971f15160113b04e86.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0009-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/cde4e1137364cf971f15160113b04e86.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0009-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/cde4e1137364cf971f15160113b04e86.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0009-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/cde4e1137364cf971f15160113b04e86.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0009-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/cde4e1137364cf971f15160113b04e86.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0009-512.png","team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"updated":1451916406,"is_app_user":false,"presence":"away"},{"id":"U0HPMN0GY","team_id":"T04KB5WQH","name":"slak","deleted":true,"profile":{"first_name":"API
138
+ Explorer","bot_id":"B0HPLG4M7","api_app_id":"A0HP7340N","avatar_hash":"36be3c0d4513","image_24":"https:\/\/avatars.slack-edge.com\/2016-01-21\/19073458786_36be3c0d451350c9f03b_24.png","image_32":"https:\/\/avatars.slack-edge.com\/2016-01-21\/19073458786_36be3c0d451350c9f03b_32.png","image_48":"https:\/\/avatars.slack-edge.com\/2016-01-21\/19073458786_36be3c0d451350c9f03b_48.png","image_72":"https:\/\/avatars.slack-edge.com\/2016-01-21\/19073458786_36be3c0d451350c9f03b_72.png","image_192":"https:\/\/avatars.slack-edge.com\/2016-01-21\/19073458786_36be3c0d451350c9f03b_192.png","image_512":"https:\/\/avatars.slack-edge.com\/2016-01-21\/19073458786_36be3c0d451350c9f03b_512.png","image_1024":"https:\/\/avatars.slack-edge.com\/2016-01-21\/19073458786_36be3c0d451350c9f03b_512.png","image_original":"https:\/\/avatars.slack-edge.com\/2016-01-21\/19073458786_36be3c0d451350c9f03b_original.png","real_name":"API
139
+ Explorer","real_name_normalized":"API Explorer","team":"T04KB5WQH"},"is_bot":true,"updated":1453387970,"is_app_user":false,"presence":"away"},{"id":"U0J1GAHN1","team_id":"T04KB5WQH","name":"travis-ci","deleted":false,"color":"5a4592","real_name":"","tz":null,"tz_label":"Pacific
140
+ Daylight Time","tz_offset":-25200,"profile":{"bot_id":"B0J1L75DY","api_app_id":"","avatar_hash":"dd0191970c25","image_24":"https:\/\/avatars.slack-edge.com\/2016-01-08\/18054871664_dd0191970c25e54ef23f_24.png","image_32":"https:\/\/avatars.slack-edge.com\/2016-01-08\/18054871664_dd0191970c25e54ef23f_32.png","image_48":"https:\/\/avatars.slack-edge.com\/2016-01-08\/18054871664_dd0191970c25e54ef23f_48.png","image_72":"https:\/\/avatars.slack-edge.com\/2016-01-08\/18054871664_dd0191970c25e54ef23f_72.png","image_192":"https:\/\/avatars.slack-edge.com\/2016-01-08\/18054871664_dd0191970c25e54ef23f_192.png","image_512":"https:\/\/avatars.slack-edge.com\/2016-01-08\/18054871664_dd0191970c25e54ef23f_512.png","image_1024":"https:\/\/avatars.slack-edge.com\/2016-01-08\/18054871664_dd0191970c25e54ef23f_512.png","image_original":"https:\/\/avatars.slack-edge.com\/2016-01-08\/18054871664_dd0191970c25e54ef23f_original.png","title":"Used
141
+ for Travis-CI integration tests on https:\/\/github.com\/dblock\/slack-ruby-client.","real_name":"","real_name_normalized":"","team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"updated":1452271052,"is_app_user":false,"presence":"away"},{"id":"U0LAVPSLF","team_id":"T04KB5WQH","name":"market","deleted":false,"color":"db3150","real_name":"Market","tz":null,"tz_label":"Pacific
142
+ Daylight Time","tz_offset":-25200,"profile":{"bot_id":"B0LAPCFT6","api_app_id":"A0LAU0998","first_name":"Market","avatar_hash":"522645c5607a","image_24":"https:\/\/avatars.slack-edge.com\/2016-06-12\/50217631700_522645c5607acc032c6f_24.png","image_32":"https:\/\/avatars.slack-edge.com\/2016-06-12\/50217631700_522645c5607acc032c6f_32.png","image_48":"https:\/\/avatars.slack-edge.com\/2016-06-12\/50217631700_522645c5607acc032c6f_48.png","image_72":"https:\/\/avatars.slack-edge.com\/2016-06-12\/50217631700_522645c5607acc032c6f_72.png","image_192":"https:\/\/avatars.slack-edge.com\/2016-06-12\/50217631700_522645c5607acc032c6f_192.png","image_512":"https:\/\/avatars.slack-edge.com\/2016-06-12\/50217631700_522645c5607acc032c6f_512.png","image_1024":"https:\/\/avatars.slack-edge.com\/2016-06-12\/50217631700_522645c5607acc032c6f_512.png","image_original":"https:\/\/avatars.slack-edge.com\/2016-06-12\/50217631700_522645c5607acc032c6f_original.png","real_name":"Market","real_name_normalized":"Market","team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"updated":1465761630,"is_app_user":false,"presence":"active"},{"id":"U0RU32XGB","team_id":"T04KB5WQH","name":"demo_app","deleted":true,"profile":{"bot_id":"B0S04SHFX","api_app_id":"A0S05U5H7","first_name":"Demo
143
+ App","avatar_hash":"g470eaf566ca","real_name":"Demo App","real_name_normalized":"Demo
144
+ App","image_24":"https:\/\/secure.gravatar.com\/avatar\/470eaf566ca842e4c7a2a6113aaabeff.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0006-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/470eaf566ca842e4c7a2a6113aaabeff.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0006-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/470eaf566ca842e4c7a2a6113aaabeff.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0006-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/470eaf566ca842e4c7a2a6113aaabeff.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0006-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/470eaf566ca842e4c7a2a6113aaabeff.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0006-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/470eaf566ca842e4c7a2a6113aaabeff.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0006-512.png","team":"T04KB5WQH"},"is_bot":true,"updated":1457642340,"is_app_user":false,"presence":"away"}],"cache_ts":1504042259,"response_metadata":{"next_cursor":"dXNlcjpVMFMwRzAyOEs="}}'
145
+ http_version:
146
+ recorded_at: Tue, 29 Aug 2017 21:30:59 GMT
147
+ - request:
148
+ method: post
149
+ uri: https://slack.com/api/users.list
150
+ body:
151
+ encoding: UTF-8
152
+ string: cursor=dXNlcjpVMFMwRzAyOEs%3D&limit=5&presence=true&token=token
153
+ headers:
154
+ Accept:
155
+ - application/json; charset=utf-8
156
+ User-Agent:
157
+ - Slack Ruby Client/0.9.2
158
+ Content-Type:
159
+ - application/x-www-form-urlencoded
160
+ Accept-Encoding:
161
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
162
+ response:
163
+ status:
164
+ code: 200
165
+ message: OK
166
+ headers:
167
+ Content-Type:
168
+ - application/json; charset=utf-8
169
+ body:
170
+ encoding: ASCII-8BIT
171
+ string: '{"ok":true,"members":[{"id":"U0S0G028K","team_id":"T04KB5WQH","name":"demofoo","deleted":true,"profile":{"bot_id":"B0S21UP2L","api_app_id":"A0S212AD7","first_name":"Demo
172
+ App","avatar_hash":"g7ff909dc801","real_name":"Demo App","real_name_normalized":"Demo
173
+ App","image_24":"https:\/\/secure.gravatar.com\/avatar\/7ff909dc801e9b78da70deb57d6a9548.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0023-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/7ff909dc801e9b78da70deb57d6a9548.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0023-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/7ff909dc801e9b78da70deb57d6a9548.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0023-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/7ff909dc801e9b78da70deb57d6a9548.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F3654%2Fimg%2Favatars%2Fava_0023-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/7ff909dc801e9b78da70deb57d6a9548.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0023-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/7ff909dc801e9b78da70deb57d6a9548.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0023-512.png","team":"T04KB5WQH"},"is_bot":true,"updated":1457698194,"is_app_user":false,"presence":"away"},{"id":"U6HMJSC01","team_id":"T04KB5WQH","name":"test_app","deleted":false,"color":"53b759","real_name":"Test
174
+ App","tz":null,"tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"bot_id":"B6KAQDLCF","api_app_id":"A19GAJ72T","always_active":false,"first_name":"Test
175
+ App","avatar_hash":"g620010e14ef","real_name":"Test App","real_name_normalized":"Test
176
+ App","image_24":"https:\/\/secure.gravatar.com\/avatar\/620010e14ef438a65db182bd767da3bc.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0006-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/620010e14ef438a65db182bd767da3bc.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0006-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/620010e14ef438a65db182bd767da3bc.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0006-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/620010e14ef438a65db182bd767da3bc.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0006-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/620010e14ef438a65db182bd767da3bc.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0006-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/620010e14ef438a65db182bd767da3bc.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0006-512.png","team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"updated":1503251742,"is_app_user":false,"presence":"away"},{"id":"U6QNX3JR5","team_id":"T04KB5WQH","name":"dblockplayplay","deleted":false,"color":"c386df","real_name":"Daniel
177
+ Play","tz":"America\/New_York","tz_label":"Eastern Daylight Time","tz_offset":-14400,"profile":{"first_name":"Daniel","last_name":"Play","avatar_hash":"gedc34867051","title":"","real_name":"Daniel
178
+ Play","real_name_normalized":"Daniel Play","email":"dblock+example.com.org","image_24":"https:\/\/secure.gravatar.com\/avatar\/edc348670516c40654a171bdc09709b1.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F0180%2Fimg%2Favatars%2Fava_0003-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/edc348670516c40654a171bdc09709b1.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0003-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/edc348670516c40654a171bdc09709b1.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0003-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/edc348670516c40654a171bdc09709b1.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0003-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/edc348670516c40654a171bdc09709b1.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0003-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/edc348670516c40654a171bdc09709b1.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0003-512.png","team":"T04KB5WQH"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"updated":1502923687,"is_app_user":false,"presence":"away"}],"cache_ts":1504042260,"response_metadata":{"next_cursor":""}}'
179
+ http_version:
180
+ recorded_at: Tue, 29 Aug 2017 21:31:00 GMT
181
+ recorded_with: VCR 3.0.3
@@ -51,7 +51,7 @@ RSpec.describe 'integration test', skip: (!ENV['SLACK_API_TOKEN'] || !ENV['CONCU
51
51
  end
52
52
 
53
53
  def start_server
54
- dt = rand(5) + 1
54
+ dt = rand(5) + 2
55
55
  logger.debug "#start_server, waiting #{dt} second(s)"
56
56
  sleep dt # prevent Slack 429 rate limit errors
57
57
  # start server and wait for on :open
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+
2
2
  require 'spec_helper'
3
3
 
4
4
  describe Slack::Messages::Formatting do
@@ -53,7 +53,7 @@ RSpec.describe Slack::RealTime::Client do
53
53
  allow(socket).to receive(:start_sync)
54
54
  client.start!
55
55
  end
56
- context 'properties provided upon connection' do
56
+ describe 'properties provided upon connection' do
57
57
  it 'sets url' do
58
58
  expect(client.url).to eq url
59
59
  end
@@ -117,7 +117,6 @@ RSpec.describe Slack::RealTime::Client do
117
117
  end
118
118
  end
119
119
  context 'subclassed' do
120
- let(:client) { Class.new(Slack::RealTime::Client).new(store_class: Slack::RealTime::Stores::Store) }
121
120
  it 'runs event handlers' do
122
121
  event = Slack::RealTime::Event.new(
123
122
  'type' => 'team_rename',
@@ -129,8 +128,8 @@ RSpec.describe Slack::RealTime::Client do
129
128
  end
130
129
  end
131
130
  end
132
- context 'client with a default store', vcr: { cassette_name: 'web/rtm_connect' } do
133
- let(:client) { Slack::RealTime::Client.new }
131
+ context 'client with starter store', vcr: { cassette_name: 'web/rtm_connect' } do
132
+ let(:client) { Slack::RealTime::Client.new(store_class: Slack::RealTime::Stores::Starter) }
134
133
  let(:url) { 'wss://mpmulti-w5tz.slack-msgs.com/websocket/uid' }
135
134
  describe '#start!' do
136
135
  let(:socket) { double(Slack::RealTime::Socket, connected?: true) }
@@ -140,35 +139,33 @@ RSpec.describe Slack::RealTime::Client do
140
139
  allow(socket).to receive(:start_sync)
141
140
  client.start!
142
141
  end
143
- context 'properties provided upon connection' do
142
+ describe 'properties provided upon connection' do
144
143
  it 'sets url' do
145
144
  expect(client.url).to eq url
146
145
  end
147
146
  it 'sets team' do
148
147
  expect(client.team.domain).to eq 'dblockdotorg'
149
148
  end
150
- it 'sets teams' do
151
- expect(client.teams.count).to eq 1
152
- expect(client.teams.values.first).to eq client.team
153
- end
154
149
  it 'sets self' do
155
150
  expect(client.self.id).to eq 'U07518DTL'
156
151
  end
157
- it 'sets user' do
158
- expect(client.users.count).to eq 1
159
- expect(client.users.values.first['id']).to eq 'U07518DTL'
152
+ it 'no users' do
153
+ expect(client.users).to be_nil
154
+ end
155
+ it 'no teams' do
156
+ expect(client.teams).to be_nil
160
157
  end
161
158
  it 'no channels' do
162
- expect(client.channels.count).to eq 0
159
+ expect(client.channels).to be_nil
163
160
  end
164
161
  it 'no ims' do
165
- expect(client.ims.count).to eq 0
162
+ expect(client.ims).to be_nil
166
163
  end
167
164
  it 'no bots' do
168
- expect(client.bots.count).to eq 0
165
+ expect(client.bots).to be_nil
169
166
  end
170
167
  it 'no groups' do
171
- expect(client.groups.count).to eq 0
168
+ expect(client.groups).to be_nil
172
169
  end
173
170
  end
174
171
  it 'uses web client to fetch url' do
@@ -200,46 +197,47 @@ RSpec.describe Slack::RealTime::Client do
200
197
  expect(client.send(:next_id)).to eq previous_id + 1
201
198
  end
202
199
  end
203
- context 'store_class: nil' do
204
- let(:client) { Slack::RealTime::Client.new(store_class: nil) }
205
- it 'sets store to nil' do
206
- expect(client.store).to be nil
207
- end
208
- it "doesn't handle events" do
209
- event = Slack::RealTime::Event.new(
210
- 'type' => 'team_rename',
211
- 'name' => 'New Team Name Inc.'
212
- )
213
- expect(client).to_not receive(:run_handlers)
214
- client.send(:dispatch, event)
215
- end
216
- it 'self' do
217
- expect(client.self).to be nil
218
- end
219
- it 'team' do
220
- expect(client.team).to be nil
221
- end
222
- end
223
200
  end
224
- context 'with defaults' do
225
- let(:client) { Slack::RealTime::Client.new }
226
- describe '#initialize' do
227
- it 'sets ping' do
228
- expect(client.websocket_ping).to eq 30
229
- end
230
- it "doesn't set proxy" do
231
- expect(client.websocket_proxy).to be nil
232
- end
233
- it 'defaults logger' do
234
- expect(client.send(:logger)).to be_a ::Logger
235
- end
236
- it 'sets default store_class' do
237
- expect(client.send(:store_class)).to eq Slack::RealTime::Store
238
- end
239
- (Slack::RealTime::Config::ATTRIBUTES - [:logger, :store_class]).each do |key|
240
- it "sets #{key}" do
241
- expect(client.send(key)).to eq Slack::RealTime::Config.send(key)
242
- end
201
+ end
202
+ context 'client with nil store', vcr: { cassette_name: 'web/rtm_connect' } do
203
+ let(:client) { Slack::RealTime::Client.new(store_class: nil) }
204
+ let(:url) { 'wss://mpmulti-w5tz.slack-msgs.com/websocket/uid' }
205
+ it 'sets store to nil' do
206
+ expect(client.store).to be nil
207
+ end
208
+ it "doesn't handle events" do
209
+ event = Slack::RealTime::Event.new(
210
+ 'type' => 'team_rename',
211
+ 'name' => 'New Team Name Inc.'
212
+ )
213
+ expect(client).to_not receive(:run_handlers)
214
+ client.send(:dispatch, event)
215
+ end
216
+ it 'self' do
217
+ expect(client.self).to be nil
218
+ end
219
+ it 'team' do
220
+ expect(client.team).to be nil
221
+ end
222
+ end
223
+ context 'client with defaults' do
224
+ let(:client) { Slack::RealTime::Client.new }
225
+ describe '#initialize' do
226
+ it 'sets ping' do
227
+ expect(client.websocket_ping).to eq 30
228
+ end
229
+ it "doesn't set proxy" do
230
+ expect(client.websocket_proxy).to be nil
231
+ end
232
+ it 'defaults logger' do
233
+ expect(client.send(:logger)).to be_a ::Logger
234
+ end
235
+ it 'sets default store_class' do
236
+ expect(client.send(:store_class)).to eq Slack::RealTime::Store
237
+ end
238
+ (Slack::RealTime::Config::ATTRIBUTES - %i[logger store_class]).each do |key|
239
+ it "sets #{key}" do
240
+ expect(client.send(key)).to eq Slack::RealTime::Config.send(key)
243
241
  end
244
242
  end
245
243
  end
@@ -261,7 +259,7 @@ RSpec.describe Slack::RealTime::Client do
261
259
  after do
262
260
  Slack::RealTime::Client.config.reset
263
261
  end
264
- let(:url) { 'wss://mpmulti-w5tz.slack-msgs.com/websocket/uid' }
262
+ let(:url) { 'wss://ms173.slack-msgs.com/websocket/lqcUiAvrKTP-uuid=' }
265
263
  let(:client) { Slack::RealTime::Client.new }
266
264
  context 'ping' do
267
265
  before do
@@ -273,7 +271,7 @@ RSpec.describe Slack::RealTime::Client do
273
271
  it 'sets ping' do
274
272
  expect(client.websocket_ping).to eq 15
275
273
  end
276
- it 'creates a connection with custom ping', vcr: { cassette_name: 'web/rtm_connect' } do
274
+ it 'creates a connection with custom ping', vcr: { cassette_name: 'web/rtm_start' } do
277
275
  expect(Slack::RealTime::Concurrency::Mock::WebSocket).to receive(:new).with(url, nil, ping: 15).and_return(ws)
278
276
  client.start!
279
277
  end
@@ -298,7 +296,7 @@ RSpec.describe Slack::RealTime::Client do
298
296
  headers: { 'User-Agent' => 'ruby' }
299
297
  )
300
298
  end
301
- it 'creates a connection with custom proxy', vcr: { cassette_name: 'web/rtm_connect' } do
299
+ it 'creates a connection with custom proxy', vcr: { cassette_name: 'web/rtm_start' } do
302
300
  expect(Slack::RealTime::Concurrency::Mock::WebSocket).to receive(:new).with(
303
301
  url,
304
302
  nil,
@@ -306,7 +304,8 @@ RSpec.describe Slack::RealTime::Client do
306
304
  proxy: {
307
305
  origin: 'http://username:password@proxy.example.com',
308
306
  headers: { 'User-Agent' => 'ruby' }
309
- }).and_return(ws)
307
+ }
308
+ ).and_return(ws)
310
309
  client.start!
311
310
  end
312
311
  end
@@ -328,8 +327,8 @@ RSpec.describe Slack::RealTime::Client do
328
327
  allow(socket).to receive(:connect!)
329
328
  allow(socket).to receive(:start_sync)
330
329
  end
331
- it 'calls rtm_start with start options', vcr: { cassette_name: 'web/rtm_connect' } do
332
- expect(client.web_client).to receive(:rtm_connect).with(simple_latest: true).and_call_original
330
+ it 'calls rtm_start with start options', vcr: { cassette_name: 'web/rtm_start' } do
331
+ expect(client.web_client).to receive(:rtm_start).with(simple_latest: true).and_call_original
333
332
  client.start!
334
333
  end
335
334
  end
@@ -415,8 +414,8 @@ RSpec.describe Slack::RealTime::Client do
415
414
  allow(socket).to receive(:connect!)
416
415
  allow(socket).to receive(:start_sync)
417
416
  end
418
- it 'defaults to :rtm_connect', vcr: { cassette_name: 'web/rtm_connect' } do
419
- expect(client.web_client).to receive(:rtm_connect).and_call_original
417
+ it 'defaults to :rtm_start when using full store', vcr: { cassette_name: 'web/rtm_start' } do
418
+ expect(client.web_client).to receive(:rtm_start).and_call_original
420
419
  client.start!
421
420
  end
422
421
  end