slack-ruby-client 0.7.2 → 1.0.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 (383) hide show
  1. checksums.yaml +5 -5
  2. data/.github/FUNDING.yml +1 -0
  3. data/.gitignore +2 -0
  4. data/.gitmodules +1 -1
  5. data/.rubocop.yml +37 -1
  6. data/.rubocop_todo.yml +130 -47
  7. data/.travis.yml +17 -13
  8. data/CHANGELOG.md +254 -43
  9. data/CONTRIBUTING.md +26 -15
  10. data/Dangerfile +3 -0
  11. data/Gemfile +13 -2
  12. data/LICENSE.md +1 -1
  13. data/README.md +287 -63
  14. data/RELEASING.md +22 -14
  15. data/Rakefile +2 -1
  16. data/UPGRADING.md +129 -5
  17. data/bin/commands/admin_analytics.rb +16 -0
  18. data/bin/commands/admin_apps.rb +51 -0
  19. data/bin/commands/admin_apps_approved.rb +17 -0
  20. data/bin/commands/admin_apps_requests.rb +17 -0
  21. data/bin/commands/admin_apps_restricted.rb +17 -0
  22. data/bin/commands/admin_auth_policy.rb +39 -0
  23. data/bin/commands/admin_barriers.rb +47 -0
  24. data/bin/commands/admin_conversations.rb +169 -0
  25. data/bin/commands/admin_conversations_ekm.rb +17 -0
  26. data/bin/commands/admin_conversations_restrictAccess.rb +37 -0
  27. data/bin/commands/admin_conversations_whitelist.rb +37 -0
  28. data/bin/commands/admin_emoji.rb +54 -0
  29. data/bin/commands/admin_inviteRequests.rb +36 -0
  30. data/bin/commands/admin_inviteRequests_approved.rb +16 -0
  31. data/bin/commands/admin_inviteRequests_denied.rb +16 -0
  32. data/bin/commands/admin_teams.rb +27 -0
  33. data/bin/commands/admin_teams_admins.rb +16 -0
  34. data/bin/commands/admin_teams_owners.rb +16 -0
  35. data/bin/commands/admin_teams_settings.rb +64 -0
  36. data/bin/commands/admin_usergroups.rb +48 -0
  37. data/bin/commands/admin_users.rb +98 -0
  38. data/bin/commands/admin_users_session.rb +78 -0
  39. data/bin/commands/api.rb +3 -3
  40. data/bin/commands/apps.rb +15 -0
  41. data/bin/commands/apps_connections.rb +13 -0
  42. data/bin/commands/apps_event_authorizations.rb +16 -0
  43. data/bin/commands/apps_manifest.rb +51 -0
  44. data/bin/commands/apps_permissions.rb +23 -0
  45. data/bin/commands/apps_permissions_resources.rb +15 -0
  46. data/bin/commands/apps_permissions_scopes.rb +13 -0
  47. data/bin/commands/apps_permissions_users.rb +26 -0
  48. data/bin/commands/auth.rb +12 -2
  49. data/bin/commands/auth_teams.rb +16 -0
  50. data/bin/commands/bots.rb +15 -0
  51. data/bin/commands/calls.rb +52 -0
  52. data/bin/commands/calls_participants.rb +25 -0
  53. data/bin/commands/channels.rb +6 -132
  54. data/bin/commands/chat.rb +127 -20
  55. data/bin/commands/chat_scheduledMessages.rb +19 -0
  56. data/bin/commands/conversations.rb +253 -0
  57. data/bin/commands/dialog.rb +15 -0
  58. data/bin/commands/dnd.rb +12 -9
  59. data/bin/commands/emoji.rb +3 -2
  60. data/bin/commands/files.rb +47 -31
  61. data/bin/commands/files_comments.rb +3 -23
  62. data/bin/commands/files_remote.rb +78 -0
  63. data/bin/commands/groups.rb +1 -154
  64. data/bin/commands/im.rb +1 -48
  65. data/bin/commands/migration.rb +16 -0
  66. data/bin/commands/mpim.rb +1 -48
  67. data/bin/commands/oauth.rb +4 -2
  68. data/bin/commands/oauth_v2.rb +29 -0
  69. data/bin/commands/openid_connect.rb +27 -0
  70. data/bin/commands/pins.rb +9 -12
  71. data/bin/commands/reactions.rb +17 -15
  72. data/bin/commands/reminders.rb +17 -10
  73. data/bin/commands/rtm.rb +19 -4
  74. data/bin/commands/search.rb +17 -12
  75. data/bin/commands/stars.rb +12 -9
  76. data/bin/commands/team.rb +23 -8
  77. data/bin/commands/team_billing.rb +13 -0
  78. data/bin/commands/team_preferences.rb +13 -0
  79. data/bin/commands/team_profile.rb +14 -0
  80. data/bin/commands/tooling_tokens.rb +14 -0
  81. data/bin/commands/usergroups.rb +23 -17
  82. data/bin/commands/usergroups_users.rb +7 -4
  83. data/bin/commands/users.rb +83 -27
  84. data/bin/commands/users_admin.rb +29 -0
  85. data/bin/commands/users_prefs.rb +13 -0
  86. data/bin/commands/users_profile.rb +27 -0
  87. data/bin/commands/views.rb +48 -0
  88. data/bin/commands/workflows.rb +38 -0
  89. data/bin/commands.rb +47 -5
  90. data/bin/slack +3 -4
  91. data/examples/hi_real_time_and_web/Gemfile +1 -0
  92. data/examples/hi_real_time_and_web/hi.rb +8 -4
  93. data/examples/{hi_real_time_async_celluloid → hi_real_time_async_async}/Gemfile +2 -1
  94. data/examples/{hi_real_time_async_celluloid → hi_real_time_async_async}/Procfile +0 -0
  95. data/examples/{hi_real_time_async_celluloid → hi_real_time_async_async}/hi.rb +13 -8
  96. data/examples/hi_web/Gemfile +1 -0
  97. data/examples/hi_web/hi.rb +2 -1
  98. data/examples/new_ticket/Gemfile +1 -0
  99. data/examples/new_ticket/new_ticket.rb +3 -2
  100. data/lib/slack/config.rb +2 -2
  101. data/lib/slack/events/config.rb +32 -0
  102. data/lib/slack/events/request.rb +72 -0
  103. data/lib/slack/logger.rb +6 -5
  104. data/lib/slack/messages/formatting.rb +4 -4
  105. data/lib/slack/messages/message.rb +6 -4
  106. data/lib/slack/real_time/api/message.rb +3 -1
  107. data/lib/slack/real_time/api/message_id.rb +1 -0
  108. data/lib/slack/real_time/api/ping.rb +5 -2
  109. data/lib/slack/real_time/api/templates/event_handler.erb +1 -1
  110. data/lib/slack/real_time/api/typing.rb +3 -1
  111. data/lib/slack/real_time/client.rb +116 -36
  112. data/lib/slack/real_time/concurrency/async.rb +138 -0
  113. data/lib/slack/real_time/concurrency.rb +2 -2
  114. data/lib/slack/real_time/config.rb +17 -19
  115. data/lib/slack/real_time/models/base.rb +3 -3
  116. data/lib/slack/real_time/models/bot.rb +1 -0
  117. data/lib/slack/real_time/models/channel.rb +1 -0
  118. data/lib/slack/real_time/models/group.rb +1 -0
  119. data/lib/slack/real_time/models/im.rb +1 -0
  120. data/lib/slack/real_time/models/team.rb +1 -0
  121. data/lib/slack/real_time/models/user.rb +1 -0
  122. data/lib/slack/real_time/models.rb +8 -7
  123. data/lib/slack/real_time/socket.rb +51 -23
  124. data/lib/slack/real_time/stores/base.rb +6 -9
  125. data/lib/slack/real_time/stores/starter.rb +143 -69
  126. data/lib/slack/real_time/stores/store.rb +160 -82
  127. data/lib/slack/real_time/stores.rb +4 -3
  128. data/lib/slack/version.rb +2 -1
  129. data/lib/slack/web/api/endpoints/admin_analytics.rb +28 -0
  130. data/lib/slack/web/api/endpoints/admin_apps.rb +78 -0
  131. data/lib/slack/web/api/endpoints/admin_apps_approved.rb +35 -0
  132. data/lib/slack/web/api/endpoints/admin_apps_requests.rb +35 -0
  133. data/lib/slack/web/api/endpoints/admin_apps_restricted.rb +35 -0
  134. data/lib/slack/web/api/endpoints/admin_auth_policy.rb +72 -0
  135. data/lib/slack/web/api/endpoints/admin_barriers.rb +82 -0
  136. data/lib/slack/web/api/endpoints/admin_conversations.rb +260 -0
  137. data/lib/slack/web/api/endpoints/admin_conversations_ekm.rb +35 -0
  138. data/lib/slack/web/api/endpoints/admin_conversations_restrictAccess.rb +61 -0
  139. data/lib/slack/web/api/endpoints/admin_conversations_whitelist.rb +64 -0
  140. data/lib/slack/web/api/endpoints/admin_emoji.rb +88 -0
  141. data/lib/slack/web/api/endpoints/admin_inviteRequests.rb +61 -0
  142. data/lib/slack/web/api/endpoints/admin_inviteRequests_approved.rb +33 -0
  143. data/lib/slack/web/api/endpoints/admin_inviteRequests_denied.rb +33 -0
  144. data/lib/slack/web/api/endpoints/admin_teams.rb +50 -0
  145. data/lib/slack/web/api/endpoints/admin_teams_admins.rb +34 -0
  146. data/lib/slack/web/api/endpoints/admin_teams_owners.rb +34 -0
  147. data/lib/slack/web/api/endpoints/admin_teams_settings.rb +99 -0
  148. data/lib/slack/web/api/endpoints/admin_usergroups.rb +77 -0
  149. data/lib/slack/web/api/endpoints/admin_users.rb +163 -0
  150. data/lib/slack/web/api/endpoints/admin_users_session.rb +122 -0
  151. data/lib/slack/web/api/endpoints/api.rb +4 -5
  152. data/lib/slack/web/api/endpoints/apps.rb +27 -0
  153. data/lib/slack/web/api/endpoints/apps_connections.rb +21 -0
  154. data/lib/slack/web/api/endpoints/apps_event_authorizations.rb +34 -0
  155. data/lib/slack/web/api/endpoints/apps_manifest.rb +75 -0
  156. data/lib/slack/web/api/endpoints/apps_permissions.rb +36 -0
  157. data/lib/slack/web/api/endpoints/apps_permissions_resources.rb +31 -0
  158. data/lib/slack/web/api/endpoints/apps_permissions_scopes.rb +21 -0
  159. data/lib/slack/web/api/endpoints/apps_permissions_users.rb +50 -0
  160. data/lib/slack/web/api/endpoints/auth.rb +14 -2
  161. data/lib/slack/web/api/endpoints/auth_teams.rb +33 -0
  162. data/lib/slack/web/api/endpoints/bots.rb +25 -0
  163. data/lib/slack/web/api/endpoints/calls.rb +83 -0
  164. data/lib/slack/web/api/endpoints/calls_participants.rb +42 -0
  165. data/lib/slack/web/api/endpoints/channels.rb +8 -201
  166. data/lib/slack/web/api/endpoints/chat.rb +252 -42
  167. data/lib/slack/web/api/endpoints/chat_scheduledMessages.rb +40 -0
  168. data/lib/slack/web/api/endpoints/conversations.rb +422 -0
  169. data/lib/slack/web/api/endpoints/dialog.rb +33 -0
  170. data/lib/slack/web/api/endpoints/dnd.rb +17 -12
  171. data/lib/slack/web/api/endpoints/emoji.rb +3 -2
  172. data/lib/slack/web/api/endpoints/files.rb +82 -43
  173. data/lib/slack/web/api/endpoints/files_comments.rb +4 -36
  174. data/lib/slack/web/api/endpoints/files_remote.rb +127 -0
  175. data/lib/slack/web/api/endpoints/groups.rb +1 -235
  176. data/lib/slack/web/api/endpoints/im.rb +1 -73
  177. data/lib/slack/web/api/endpoints/migration.rb +28 -0
  178. data/lib/slack/web/api/endpoints/mpim.rb +1 -72
  179. data/lib/slack/web/api/endpoints/oauth.rb +9 -10
  180. data/lib/slack/web/api/endpoints/oauth_v2.rb +48 -0
  181. data/lib/slack/web/api/endpoints/openid_connect.rb +42 -0
  182. data/lib/slack/web/api/endpoints/pins.rb +14 -23
  183. data/lib/slack/web/api/endpoints/presence.rb +1 -1
  184. data/lib/slack/web/api/endpoints/reactions.rb +43 -34
  185. data/lib/slack/web/api/endpoints/reminders.rb +28 -15
  186. data/lib/slack/web/api/endpoints/rtm.rb +29 -8
  187. data/lib/slack/web/api/endpoints/search.rb +39 -24
  188. data/lib/slack/web/api/endpoints/stars.rb +30 -22
  189. data/lib/slack/web/api/endpoints/team.rb +34 -11
  190. data/lib/slack/web/api/endpoints/team_billing.rb +21 -0
  191. data/lib/slack/web/api/endpoints/team_preferences.rb +21 -0
  192. data/lib/slack/web/api/endpoints/team_profile.rb +23 -0
  193. data/lib/slack/web/api/endpoints/tooling_tokens.rb +24 -0
  194. data/lib/slack/web/api/endpoints/usergroups.rb +43 -32
  195. data/lib/slack/web/api/endpoints/usergroups_users.rb +14 -9
  196. data/lib/slack/web/api/endpoints/users.rb +104 -19
  197. data/lib/slack/web/api/endpoints/users_admin.rb +49 -0
  198. data/lib/slack/web/api/endpoints/users_prefs.rb +21 -0
  199. data/lib/slack/web/api/endpoints/users_profile.rb +44 -0
  200. data/lib/slack/web/api/endpoints/views.rb +97 -0
  201. data/lib/slack/web/api/endpoints/workflows.rb +61 -0
  202. data/lib/slack/web/api/endpoints.rb +111 -29
  203. data/lib/slack/web/api/error.rb +2 -8
  204. data/lib/slack/web/api/errors/server_error.rb +37 -0
  205. data/lib/slack/web/api/errors/slack_error.rb +29 -0
  206. data/lib/slack/web/api/errors/too_many_requests_error.rb +21 -0
  207. data/lib/slack/web/api/errors.rb +1040 -0
  208. data/lib/slack/web/api/mixins/conversations.id.rb +25 -0
  209. data/lib/slack/web/api/mixins/ids.id.rb +24 -0
  210. data/lib/slack/web/api/mixins/users.id.rb +6 -7
  211. data/lib/slack/web/api/mixins/users.search.rb +39 -36
  212. data/lib/slack/web/api/mixins.rb +4 -4
  213. data/lib/slack/web/api/patches/chat.1.patch +70 -0
  214. data/lib/slack/web/api/patches/dialog.1.open-json-support.patch +17 -0
  215. data/lib/slack/web/api/patches/views.1.view-json.patch +40 -0
  216. data/lib/slack/web/api/patches/views.1.views-published.patch +16 -0
  217. data/lib/slack/web/api/templates/command.erb +5 -3
  218. data/lib/slack/web/api/templates/commands.erb +2 -1
  219. data/lib/slack/web/api/templates/endpoints.erb +5 -5
  220. data/lib/slack/web/api/templates/errors.erb +20 -0
  221. data/lib/slack/web/api/templates/method.erb +26 -4
  222. data/lib/slack/web/api/templates/method_spec.erb +3 -2
  223. data/lib/slack/web/client.rb +2 -1
  224. data/lib/slack/web/config.rb +21 -10
  225. data/lib/slack/web/faraday/connection.rb +25 -16
  226. data/lib/slack/web/faraday/request.rb +4 -1
  227. data/lib/slack/web/faraday/response/raise_error.rb +19 -1
  228. data/lib/slack/web/faraday/response/wrap_error.rb +24 -0
  229. data/lib/slack/web/pagination/cursor.rb +48 -0
  230. data/lib/slack-ruby-client.rb +40 -26
  231. data/lib/slack.rb +1 -0
  232. data/lib/slack_ruby_client.rb +1 -0
  233. data/lib/tasks/git.rake +2 -1
  234. data/lib/tasks/real_time.rake +16 -6
  235. data/lib/tasks/update.rake +1 -0
  236. data/lib/tasks/web.rake +42 -10
  237. data/screenshots/create-app.png +0 -0
  238. data/slack-ruby-client.gemspec +11 -9
  239. data/spec/fixtures/slack/web/429_error.yml +50 -52
  240. data/spec/fixtures/slack/web/auth_test_error.yml +51 -18
  241. data/spec/fixtures/slack/web/auth_test_success.yml +50 -26
  242. data/spec/fixtures/slack/web/conversations_info.yml +167 -0
  243. data/spec/fixtures/slack/web/conversations_setTopic.yml +84 -0
  244. data/spec/fixtures/slack/web/conversations_setTopic_one_page.yml +172 -0
  245. data/spec/fixtures/slack/web/conversations_setTopic_paginated.yml +253 -0
  246. data/spec/fixtures/slack/web/paginated_users_list.yml +613 -0
  247. data/spec/fixtures/slack/web/rtm_connect.yml +307 -0
  248. data/spec/fixtures/slack/web/rtm_start.yml +771 -60
  249. data/spec/fixtures/slack/web/users_info.yml +153 -69
  250. data/spec/fixtures/slack/web/users_list.yml +102 -41
  251. data/spec/fixtures/slack/web/views_open_error.yml +83 -0
  252. data/spec/integration/integration_spec.rb +116 -48
  253. data/spec/slack/config_spec.rb +2 -0
  254. data/spec/slack/events/config_spec.rb +33 -0
  255. data/spec/slack/events/request_spec.rb +184 -0
  256. data/spec/slack/messages/formatting_spec.rb +25 -14
  257. data/spec/slack/real_time/api/message_spec.rb +6 -1
  258. data/spec/slack/real_time/api/ping_spec.rb +2 -0
  259. data/spec/slack/real_time/api/typing_spec.rb +5 -1
  260. data/spec/slack/real_time/client_spec.rb +465 -141
  261. data/spec/slack/real_time/concurrency/it_behaves_like_a_realtime_socket.rb +21 -0
  262. data/spec/slack/real_time/concurrency/with_concurrency_spec.rb +10 -0
  263. data/spec/slack/real_time/concurrency/without_concurrency_spec.rb +10 -0
  264. data/spec/slack/real_time/event_handlers/bot_spec.rb +7 -4
  265. data/spec/slack/real_time/event_handlers/channel_spec.rb +10 -7
  266. data/spec/slack/real_time/event_handlers/event_handlers_spec.rb +3 -2
  267. data/spec/slack/real_time/event_handlers/group_spec.rb +5 -4
  268. data/spec/slack/real_time/event_handlers/im_spec.rb +9 -8
  269. data/spec/slack/real_time/event_handlers/team_spec.rb +8 -4
  270. data/spec/slack/real_time/event_handlers/user_spec.rb +7 -4
  271. data/spec/slack/real_time/rtm_connect_spec.rb +14 -0
  272. data/spec/slack/real_time/rtm_start_spec.rb +2 -1
  273. data/spec/slack/real_time/store_spec.rb +2 -1
  274. data/spec/slack/slack_spec.rb +42 -8
  275. data/spec/slack/version_spec.rb +2 -1
  276. data/spec/slack/web/api/endpoints/admin_analytics_spec.rb +13 -0
  277. data/spec/slack/web/api/endpoints/admin_apps_approved_spec.rb +8 -0
  278. data/spec/slack/web/api/endpoints/admin_apps_requests_spec.rb +8 -0
  279. data/spec/slack/web/api/endpoints/admin_apps_restricted_spec.rb +8 -0
  280. data/spec/slack/web/api/endpoints/admin_apps_spec.rb +18 -0
  281. data/spec/slack/web/api/endpoints/admin_auth_policy_spec.rb +35 -0
  282. data/spec/slack/web/api/endpoints/admin_barriers_spec.rb +38 -0
  283. data/spec/slack/web/api/endpoints/admin_conversations_ekm_spec.rb +8 -0
  284. data/spec/slack/web/api/endpoints/admin_conversations_restrictAccess_spec.rb +32 -0
  285. data/spec/slack/web/api/endpoints/admin_conversations_spec.rb +98 -0
  286. data/spec/slack/web/api/endpoints/admin_emoji_spec.rb +37 -0
  287. data/spec/slack/web/api/endpoints/admin_inviteRequests_approved_spec.rb +8 -0
  288. data/spec/slack/web/api/endpoints/admin_inviteRequests_denied_spec.rb +8 -0
  289. data/spec/slack/web/api/endpoints/admin_inviteRequests_spec.rb +18 -0
  290. data/spec/slack/web/api/endpoints/admin_teams_admins_spec.rb +13 -0
  291. data/spec/slack/web/api/endpoints/admin_teams_owners_spec.rb +13 -0
  292. data/spec/slack/web/api/endpoints/admin_teams_settings_spec.rb +53 -0
  293. data/spec/slack/web/api/endpoints/admin_teams_spec.rb +16 -0
  294. data/spec/slack/web/api/endpoints/admin_usergroups_spec.rb +37 -0
  295. data/spec/slack/web/api/endpoints/admin_users_session_spec.rb +41 -0
  296. data/spec/slack/web/api/endpoints/admin_users_spec.rb +67 -0
  297. data/spec/slack/web/api/endpoints/api_spec.rb +1 -0
  298. data/spec/slack/web/api/endpoints/apps_connections_spec.rb +8 -0
  299. data/spec/slack/web/api/endpoints/apps_event_authorizations_spec.rb +13 -0
  300. data/spec/slack/web/api/endpoints/apps_manifest_spec.rb +36 -0
  301. data/spec/slack/web/api/endpoints/apps_spec.rb +16 -0
  302. data/spec/slack/web/api/endpoints/auth_teams_spec.rb +8 -0
  303. data/spec/slack/web/api/endpoints/bots_spec.rb +8 -0
  304. data/spec/slack/web/api/endpoints/calls_participants_spec.rb +24 -0
  305. data/spec/slack/web/api/endpoints/calls_spec.rb +31 -0
  306. data/spec/slack/web/api/endpoints/chat_scheduledMessages_spec.rb +8 -0
  307. data/spec/slack/web/api/endpoints/custom_specs/auth_spec.rb +11 -4
  308. data/spec/slack/web/api/endpoints/custom_specs/chat_spec.rb +140 -24
  309. data/spec/slack/web/api/endpoints/custom_specs/conversations_spec.rb +13 -0
  310. data/spec/slack/web/api/endpoints/custom_specs/dialog_spec.rb +36 -0
  311. data/spec/slack/web/api/endpoints/custom_specs/users_spec.rb +22 -7
  312. data/spec/slack/web/api/endpoints/custom_specs/views_spec.rb +95 -0
  313. data/spec/slack/web/api/endpoints/dnd_spec.rb +4 -3
  314. data/spec/slack/web/api/endpoints/emoji_spec.rb +1 -0
  315. data/spec/slack/web/api/endpoints/files_comments_spec.rb +3 -21
  316. data/spec/slack/web/api/endpoints/files_remote_spec.rb +24 -0
  317. data/spec/slack/web/api/endpoints/files_spec.rb +17 -5
  318. data/spec/slack/web/api/endpoints/migration_spec.rb +13 -0
  319. data/spec/slack/web/api/endpoints/oauth_spec.rb +1 -11
  320. data/spec/slack/web/api/endpoints/oauth_v2_spec.rb +16 -0
  321. data/spec/slack/web/api/endpoints/openid_connect_spec.rb +8 -0
  322. data/spec/slack/web/api/endpoints/pins_spec.rb +1 -0
  323. data/spec/slack/web/api/endpoints/reactions_spec.rb +8 -1
  324. data/spec/slack/web/api/endpoints/reminders_spec.rb +3 -2
  325. data/spec/slack/web/api/endpoints/rtm_spec.rb +1 -0
  326. data/spec/slack/web/api/endpoints/search_spec.rb +1 -0
  327. data/spec/slack/web/api/endpoints/stars_spec.rb +1 -0
  328. data/spec/slack/web/api/endpoints/team_billing_spec.rb +8 -0
  329. data/spec/slack/web/api/endpoints/team_preferences_spec.rb +8 -0
  330. data/spec/slack/web/api/endpoints/team_profile_spec.rb +8 -0
  331. data/spec/slack/web/api/endpoints/team_spec.rb +1 -0
  332. data/spec/slack/web/api/endpoints/tooling_tokens_spec.rb +13 -0
  333. data/spec/slack/web/api/endpoints/usergroups_spec.rb +1 -0
  334. data/spec/slack/web/api/endpoints/usergroups_users_spec.rb +3 -2
  335. data/spec/slack/web/api/endpoints/users_admin_spec.rb +18 -0
  336. data/spec/slack/web/api/endpoints/users_prefs_spec.rb +8 -0
  337. data/spec/slack/web/api/endpoints/users_profile_spec.rb +8 -0
  338. data/spec/slack/web/api/endpoints/workflows_spec.rb +26 -0
  339. data/spec/slack/web/api/error_spec.rb +7 -7
  340. data/spec/slack/web/api/errors/slack_error_spec.rb +33 -0
  341. data/spec/slack/web/api/mixins/conversations_list_spec.rb +21 -0
  342. data/spec/slack/web/api/mixins/conversations_spec.rb +43 -0
  343. data/spec/slack/web/api/mixins/users_spec.rb +30 -17
  344. data/spec/slack/web/api/pagination/cursor_spec.rb +98 -0
  345. data/spec/slack/web/client_spec.rb +211 -14
  346. data/spec/slack/web/faraday/request_spec.rb +80 -0
  347. data/spec/slack/web/faraday/response/raise_error_spec.rb +86 -0
  348. data/spec/spec_helper.rb +9 -2
  349. data/spec/support/queue_with_timeout.rb +6 -5
  350. data/spec/support/real_time/concurrency/mock.rb +2 -2
  351. data/spec/support/real_time/connected_client.rb +7 -2
  352. data/spec/support/real_time/event.rb +1 -0
  353. data/spec/support/token.rb +1 -0
  354. data/spec/support/vcr.rb +37 -1
  355. metadata +250 -130
  356. data/examples/hi_real_time/Gemfile +0 -5
  357. data/examples/hi_real_time/hi.gif +0 -0
  358. data/examples/hi_real_time/hi.rb +0 -37
  359. data/examples/hi_real_time_async/Gemfile +0 -5
  360. data/examples/hi_real_time_async/hi.rb +0 -29
  361. data/examples/hi_real_time_async_eventmachine/Gemfile +0 -6
  362. data/examples/hi_real_time_async_eventmachine/Procfile +0 -2
  363. data/examples/hi_real_time_async_eventmachine/hi.rb +0 -36
  364. data/lib/slack/real_time/concurrency/celluloid.rb +0 -100
  365. data/lib/slack/real_time/concurrency/eventmachine.rb +0 -60
  366. data/lib/slack/web/api/mixins/channels.id.json +0 -20
  367. data/lib/slack/web/api/mixins/channels.id.rb +0 -26
  368. data/lib/slack/web/api/mixins/groups.id.json +0 -20
  369. data/lib/slack/web/api/mixins/groups.id.rb +0 -26
  370. data/lib/slack/web/api/patches/chat.1.text-attachments-required.patch +0 -13
  371. data/lib/slack/web/api/patches/chat.2.attachments-json.patch +0 -17
  372. data/lib/slack/web/api/patches/chat.3.update-attachments-support.patch +0 -20
  373. data/screenshots/register-bot.png +0 -0
  374. data/spec/fixtures/slack/web/channels_info.yml +0 -46
  375. data/spec/fixtures/slack/web/groups_info.yml +0 -43
  376. data/spec/slack/real_time/concurrency/celluloid_spec.rb +0 -35
  377. data/spec/slack/real_time/concurrency/eventmachine_spec.rb +0 -50
  378. data/spec/slack/web/api/endpoints/custom_specs/channels_spec.rb +0 -11
  379. data/spec/slack/web/api/endpoints/custom_specs/groups_spec.rb +0 -11
  380. data/spec/slack/web/api/endpoints/im_spec.rb +0 -30
  381. data/spec/slack/web/api/endpoints/mpim_spec.rb +0 -30
  382. data/spec/slack/web/api/mixins/channels_spec.rb +0 -31
  383. data/spec/slack/web/api/mixins/groups_spec.rb +0 -31
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  class Client
4
5
  class ClientNotStartedError < StandardError; end
6
+
5
7
  class ClientAlreadyStartedError < StandardError; end
6
8
 
7
9
  include Api::MessageId
@@ -15,12 +17,8 @@ module Slack
15
17
  attr_accessor :events
16
18
  end
17
19
 
18
- attr_accessor :web_client
19
- attr_accessor :store
20
- attr_accessor :url
21
- attr_accessor(*Config::ATTRIBUTES)
20
+ attr_accessor :web_client, :store, :url, *Config::ATTRIBUTES
22
21
 
23
- protected :logger, :logger=
24
22
  protected :store_class, :store_class=
25
23
 
26
24
  def initialize(options = {})
@@ -33,9 +31,9 @@ module Slack
33
31
  @web_client = Slack::Web::Client.new(token: token, logger: logger)
34
32
  end
35
33
 
36
- [:users, :self, :channels, :team, :teams, :groups, :ims, :bots].each do |store_method|
34
+ %i[users self channels team teams groups ims bots].each do |store_method|
37
35
  define_method store_method do
38
- store.send(store_method) if store
36
+ store&.send(store_method)
39
37
  end
40
38
  end
41
39
 
@@ -47,7 +45,7 @@ module Slack
47
45
  # Start RealTime client and block until it disconnects.
48
46
  def start!(&block)
49
47
  @callback = block if block_given?
50
- @socket = build_socket
48
+ build_socket
51
49
  @socket.start_sync(self)
52
50
  end
53
51
 
@@ -55,17 +53,18 @@ module Slack
55
53
  # The RealTime::Client will run in the background.
56
54
  def start_async(&block)
57
55
  @callback = block if block_given?
58
- @socket = build_socket
56
+ build_socket
59
57
  @socket.start_async(self)
60
58
  end
61
59
 
62
60
  def stop!
63
- fail ClientNotStartedError unless started?
64
- @socket.disconnect! if @socket
61
+ raise ClientNotStartedError unless started?
62
+
63
+ @socket&.disconnect!
65
64
  end
66
65
 
67
66
  def started?
68
- @socket && @socket.connected?
67
+ @socket&.connected?
69
68
  end
70
69
 
71
70
  class << self
@@ -80,38 +79,115 @@ module Slack
80
79
 
81
80
  def run_loop
82
81
  @socket.connect! do |driver|
83
- @callback.call(driver) if @callback
84
-
85
82
  driver.on :open do |event|
86
- logger.debug("#{self.class}##{__method__}") { event.class.name }
87
- open(event)
83
+ logger.debug("#{self}##{__method__}") { event.class.name }
84
+ open_event(event)
88
85
  callback(event, :open)
89
86
  end
90
87
 
91
88
  driver.on :message do |event|
92
- logger.debug("#{self.class}##{__method__}") { "#{event.class}, #{event.data}" }
89
+ logger.debug("#{self}##{__method__}") { "#{event.class}, #{event.data}" }
93
90
  dispatch(event)
94
91
  end
95
92
 
96
93
  driver.on :close do |event|
97
- logger.debug("#{self.class}##{__method__}") { event.class.name }
94
+ logger.debug("#{self}##{__method__}") { event.class.name }
98
95
  callback(event, :close)
99
96
  close(event)
100
97
  callback(event, :closed)
101
98
  end
99
+
100
+ # This must be called last to ensure any events are registered before invoking user code.
101
+ @callback&.call(driver)
102
+ end
103
+ end
104
+
105
+ # Ensure the server is running, and ping the remote server if no other messages were sent.
106
+ def keep_alive?
107
+ # We can't ping the remote server if we aren't connected.
108
+ return false if @socket.nil? || !@socket.connected?
109
+
110
+ time_since_last_message = @socket.time_since_last_message
111
+
112
+ # If the server responded within the specified time, we are okay:
113
+ return true if time_since_last_message < websocket_ping
114
+
115
+ # If the server has not responded for a while:
116
+ return false if time_since_last_message > (websocket_ping * 2)
117
+
118
+ # Kick off the next ping message:
119
+ ping
120
+
121
+ true
122
+ end
123
+
124
+ # Check if the remote server is responsive, and if not, restart the connection.
125
+ def run_ping!
126
+ return if keep_alive?
127
+
128
+ logger.warn(to_s) { 'is offline' }
129
+
130
+ restart_async
131
+ rescue Slack::Web::Api::Errors::SlackError => e
132
+ # stop pinging if bot was uninstalled
133
+ case e.message
134
+ when 'account_inactive', 'invalid_auth'
135
+ logger.warn(to_s) { e.message }
136
+ raise e
137
+ end
138
+ logger.debug("#{self}##{__method__}") { e }
139
+ rescue StandardError => e
140
+ # disregard all ping worker failures, keep pinging
141
+ logger.debug("#{self}##{__method__}") { e }
142
+ end
143
+
144
+ def run_ping?
145
+ !websocket_ping.nil? && websocket_ping.positive?
146
+ end
147
+
148
+ def websocket_ping_timer
149
+ websocket_ping / 2
150
+ end
151
+
152
+ def to_s
153
+ if store&.team
154
+ "id=#{store.team.id}, name=#{store.team.name}, domain=#{store.team.domain}"
155
+ else
156
+ super
102
157
  end
103
158
  end
104
159
 
105
160
  protected
106
161
 
162
+ def restart_async
163
+ logger.debug("#{self}##{__method__}")
164
+ @socket.close
165
+ start = web_client.send(rtm_start_method, start_options)
166
+ data = Slack::Messages::Message.new(start)
167
+ @url = data.url
168
+ @store = @store_class.new(data) if @store_class
169
+ @socket.restart_async(self, @url)
170
+ end
171
+
107
172
  # @return [Slack::RealTime::Socket]
108
173
  def build_socket
109
- fail ClientAlreadyStartedError if started?
110
- start = web_client.rtm_start(start_options)
174
+ raise ClientAlreadyStartedError if started?
175
+
176
+ start = web_client.send(rtm_start_method, start_options)
111
177
  data = Slack::Messages::Message.new(start)
112
178
  @url = data.url
113
179
  @store = @store_class.new(data) if @store_class
114
- socket_class.new(@url, socket_options)
180
+ @socket = socket_class.new(@url, socket_options)
181
+ end
182
+
183
+ def rtm_start_method
184
+ if start_method
185
+ start_method
186
+ elsif @store_class && @store_class <= Slack::RealTime::Stores::Store
187
+ :rtm_start
188
+ else
189
+ :rtm_connect
190
+ end
115
191
  end
116
192
 
117
193
  def socket_options
@@ -123,24 +199,22 @@ module Slack
123
199
  end
124
200
 
125
201
  attr_reader :callbacks
202
+
126
203
  def socket_class
127
204
  concurrency::Socket
128
205
  end
129
206
 
130
207
  def send_json(data)
131
- fail ClientNotStartedError unless started?
132
- logger.debug("#{self.class}##{__method__}") { data }
208
+ raise ClientNotStartedError unless started?
209
+
210
+ logger.debug("#{self}##{__method__}") { data }
133
211
  @socket.send_data(data.to_json)
134
212
  end
135
213
 
136
- def open(_event)
137
- end
214
+ def open_event(_event); end
138
215
 
139
216
  def close(_event)
140
- socket = @socket
141
- @socket = nil
142
-
143
- [socket, socket_class].each do |s|
217
+ [@socket, socket_class].each do |s|
144
218
  s.close if s.respond_to?(:close)
145
219
  end
146
220
  end
@@ -148,48 +222,54 @@ module Slack
148
222
  def callback(event, type)
149
223
  callbacks = self.callbacks[type.to_s]
150
224
  return false unless callbacks
225
+
151
226
  callbacks.each do |c|
152
227
  c.call(event)
153
228
  end
154
229
  true
155
230
  rescue StandardError => e
156
- logger.error e
231
+ logger.error("#{self}##{__method__}") { e }
157
232
  false
158
233
  end
159
234
 
160
235
  def dispatch(event)
161
236
  return false unless event.data
237
+
162
238
  data = Slack::Messages::Message.new(JSON.parse(event.data))
163
239
  type = data.type
164
240
  return false unless type
241
+
165
242
  type = type.to_s
166
- logger.debug("#{self.class}##{__method__}") { data.to_s }
243
+ logger.debug("#{self}##{__method__}") { data.to_s }
167
244
  run_handlers(type, data) if @store
168
245
  run_callbacks(type, data)
169
246
  rescue StandardError => e
170
- logger.error e
247
+ logger.error("#{self}##{__method__}") { e }
171
248
  false
172
249
  end
173
250
 
174
251
  def run_handlers(type, data)
252
+ return unless store.class.events
253
+
175
254
  handlers = store.class.events[type.to_s]
176
- handlers.each do |handler|
255
+ handlers&.each do |handler|
177
256
  store.instance_exec(data, &handler)
178
- end if handlers
257
+ end
179
258
  rescue StandardError => e
180
- logger.error e
259
+ logger.error("#{self}##{__method__}") { e }
181
260
  false
182
261
  end
183
262
 
184
263
  def run_callbacks(type, data)
185
264
  callbacks = self.callbacks[type]
186
265
  return false unless callbacks
266
+
187
267
  callbacks.each do |c|
188
268
  c.call(data)
189
269
  end
190
270
  true
191
271
  rescue StandardError => e
192
- logger.error e
272
+ logger.error("#{self}##{__method__}") { e }
193
273
  false
194
274
  end
195
275
  end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+ require 'async/websocket'
3
+ require 'async/notification'
4
+ require 'async/clock'
5
+
6
+ module Slack
7
+ module RealTime
8
+ module Concurrency
9
+ module Async
10
+ class Client < ::Async::WebSocket::Client
11
+ extend ::Forwardable
12
+ def_delegators :@driver, :on, :text, :binary, :emit
13
+ end
14
+
15
+ class Socket < Slack::RealTime::Socket
16
+ attr_reader :client
17
+
18
+ def start_sync(client)
19
+ start_reactor(client).wait
20
+ end
21
+
22
+ def start_async(client)
23
+ Thread.new do
24
+ start_reactor(client)
25
+ end
26
+ end
27
+
28
+ def start_reactor(client)
29
+ Async do |task|
30
+ @restart = ::Async::Notification.new
31
+
32
+ if client.run_ping?
33
+ @ping_task = task.async do |subtask|
34
+ subtask.annotate "#{client} keep-alive"
35
+
36
+ # The timer task will naturally exit after the driver is set to nil.
37
+ while @restart
38
+ subtask.sleep client.websocket_ping_timer
39
+ client.run_ping! if @restart
40
+ end
41
+ end
42
+ end
43
+
44
+ while @restart
45
+ @client_task&.stop
46
+
47
+ @client_task = task.async do |subtask|
48
+ subtask.annotate "#{client} run-loop"
49
+ client.run_loop
50
+ rescue ::Async::Wrapper::Cancelled => e
51
+ # Will get restarted by ping worker.
52
+ rescue StandardError => e
53
+ client.logger.error(subtask.to_s) { e.message }
54
+ end
55
+
56
+ @restart.wait
57
+ end
58
+
59
+ @ping_task&.stop
60
+ end
61
+ end
62
+
63
+ def restart_async(_client, new_url)
64
+ @url = new_url
65
+ @last_message_at = current_time
66
+
67
+ @restart&.signal
68
+ end
69
+
70
+ def current_time
71
+ ::Async::Clock.now
72
+ end
73
+
74
+ def connect!
75
+ super
76
+ run_loop
77
+ end
78
+
79
+ # Kill the restart/ping loop.
80
+ def disconnect!
81
+ super
82
+ ensure
83
+ if (restart = @restart)
84
+ @restart = nil
85
+ restart.signal
86
+ end
87
+ end
88
+
89
+ # Close the socket.
90
+ def close
91
+ super
92
+ ensure
93
+ if @socket
94
+ @socket.close
95
+ @socket = nil
96
+ end
97
+ end
98
+
99
+ def run_loop
100
+ while @driver&.next_event
101
+ # $stderr.puts event.inspect
102
+ end
103
+ end
104
+
105
+ protected
106
+
107
+ def build_ssl_context
108
+ OpenSSL::SSL::SSLContext.new(:TLSv1_2_client).tap do |ctx|
109
+ ctx.set_params(verify_mode: OpenSSL::SSL::VERIFY_PEER)
110
+ end
111
+ end
112
+
113
+ def build_endpoint
114
+ endpoint = ::Async::IO::Endpoint.tcp(addr, port)
115
+ endpoint = ::Async::IO::SSLEndpoint.new(endpoint, ssl_context: build_ssl_context) if secure?
116
+ endpoint
117
+ end
118
+
119
+ def connect_socket
120
+ build_endpoint.connect
121
+ end
122
+
123
+ def connect
124
+ @socket = connect_socket
125
+ @driver = Client.new(@socket, url)
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ if Gem::Version.new(Async::WebSocket::VERSION) >= Gem::Version.new('0.9.0')
134
+ raise(
135
+ "Incompatible version of async-websocket, #{Async::WebSocket::VERSION}, " \
136
+ "use \"gem 'async-websocket', '~> 0.8.0'\"."
137
+ )
138
+ end
@@ -1,8 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Concurrency
4
- autoload :Eventmachine, 'slack/real_time/concurrency/eventmachine'
5
- autoload :Celluloid, 'slack/real_time/concurrency/celluloid'
5
+ autoload :Async, 'slack/real_time/concurrency/async'
6
6
  end
7
7
  end
8
8
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Config
@@ -5,24 +6,27 @@ module Slack
5
6
 
6
7
  extend self
7
8
 
8
- ATTRIBUTES = [
9
- :token,
10
- :websocket_ping,
11
- :websocket_proxy,
12
- :concurrency,
13
- :start_options,
14
- :store_class,
15
- :logger
9
+ ATTRIBUTES = %i[
10
+ token
11
+ websocket_ping
12
+ websocket_proxy
13
+ concurrency
14
+ start_method
15
+ start_options
16
+ store_class
17
+ logger
16
18
  ].freeze
17
19
 
18
- attr_accessor(*Config::ATTRIBUTES)
20
+ attr_accessor(*Config::ATTRIBUTES - [:concurrency])
21
+ attr_writer :concurrency
19
22
 
20
23
  def reset
21
24
  self.websocket_ping = 30
22
25
  self.websocket_proxy = nil
23
26
  self.token = nil
24
27
  self.concurrency = method(:detect_concurrency)
25
- self.start_options = {}
28
+ self.start_method = nil
29
+ self.start_options = { request: { timeout: 180 } }
26
30
  self.store_class = Slack::RealTime::Store
27
31
  self.logger = nil
28
32
  end
@@ -34,15 +38,9 @@ module Slack
34
38
  private
35
39
 
36
40
  def detect_concurrency
37
- [:Eventmachine, :Celluloid].each do |concurrency|
38
- begin
39
- return Slack::RealTime::Concurrency.const_get(concurrency)
40
- rescue LoadError, NameError
41
- false # could not be loaded, missing dependencies
42
- end
43
- end
44
-
45
- fail NoConcurrencyError, 'Missing concurrency. Add faye-websocket or celluloid-io to your Gemfile.'
41
+ Slack::RealTime::Concurrency.const_get(:Async)
42
+ rescue LoadError, NameError
43
+ raise NoConcurrencyError, 'Missing concurrency. Add async-websocket to your Gemfile.'
46
44
  end
47
45
  end
48
46
 
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Models
4
5
  class Base < Hashie::Mash
5
- def presence
6
- super['presence']
7
- end
6
+ # see https://github.com/intridea/hashie/issues/394
7
+ def log_built_in_message(*); end
8
8
  end
9
9
  end
10
10
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Models
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Models
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Models
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Models
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Models
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Models
@@ -1,7 +1,8 @@
1
- require 'slack/real_time/models/base'
2
- require 'slack/real_time/models/user'
3
- require 'slack/real_time/models/bot'
4
- require 'slack/real_time/models/channel'
5
- require 'slack/real_time/models/group'
6
- require 'slack/real_time/models/team'
7
- require 'slack/real_time/models/im'
1
+ # frozen_string_literal: true
2
+ require_relative 'models/base'
3
+ require_relative 'models/user'
4
+ require_relative 'models/bot'
5
+ require_relative 'models/channel'
6
+ require_relative 'models/group'
7
+ require_relative 'models/team'
8
+ require_relative 'models/im'
@@ -1,25 +1,24 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  class Socket
4
- attr_accessor :url
5
- attr_accessor :options
5
+ attr_accessor :url, :options
6
6
  attr_reader :driver
7
- attr_reader :logger
8
- protected :logger
9
7
 
10
8
  def initialize(url, options = {})
11
9
  @url = url
12
- @options = options
10
+ @options = options.dup
13
11
  @driver = nil
14
- @logger = options.delete(:logger) || Slack::RealTime::Config.logger || Slack::Config.logger
12
+ @logger = @options.delete(:logger) || Slack::RealTime::Config.logger || Slack::Config.logger
13
+ @last_message_at = nil
15
14
  end
16
15
 
17
16
  def send_data(message)
18
17
  logger.debug("#{self.class}##{__method__}") { message }
19
18
  case message
20
- when Numeric then driver.text(message.to_s)
21
- when String then driver.text(message)
22
- when Array then driver.binary(message)
19
+ when Numeric then @driver.text(message.to_s)
20
+ when String then @driver.text(message)
21
+ when Array then @driver.binary(message)
23
22
  else false
24
23
  end
25
24
  end
@@ -28,33 +27,66 @@ module Slack
28
27
  return if connected?
29
28
 
30
29
  connect
31
- logger.debug("#{self.class}##{__method__}") { driver.class }
30
+ logger.debug("#{self.class}##{__method__}") { @driver.class }
31
+
32
+ @driver.on :message do
33
+ @last_message_at = current_time
34
+ end
32
35
 
33
- yield driver if block_given?
36
+ yield @driver if block_given?
34
37
  end
35
38
 
39
+ # Gracefully shut down the connection.
36
40
  def disconnect!
37
- driver.close
41
+ @driver.close
42
+ ensure
43
+ close
38
44
  end
39
45
 
40
46
  def connected?
41
- !driver.nil?
47
+ !@driver.nil?
42
48
  end
43
49
 
44
50
  def start_sync(client)
45
51
  thread = start_async(client)
46
- thread.join if thread
52
+ thread&.join
47
53
  rescue Interrupt
48
- thread.exit if thread
54
+ thread&.exit
49
55
  end
50
56
 
51
57
  # @return [#join]
52
58
  def start_async(_client)
53
- fail NotImplementedError, "Expected #{self.class} to implement #{__method__}."
59
+ raise NotImplementedError, "Expected #{self.class} to implement #{__method__}."
60
+ end
61
+
62
+ def restart_async(_client, _url)
63
+ raise NotImplementedError, "Expected #{self.class} to implement #{__method__}."
64
+ end
65
+
66
+ def time_since_last_message
67
+ return 0 unless @last_message_at
68
+
69
+ current_time - @last_message_at
70
+ end
71
+
72
+ def current_time
73
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
74
+ end
75
+
76
+ def close
77
+ # When you call `driver.emit(:close)`, it will typically end up calling `client.close`
78
+ # which will call `@socket.close` and end up back here. In order to break this infinite
79
+ # recursion, we check and set `@driver = nil` before invoking `client.close`.
80
+ return unless (driver = @driver)
81
+
82
+ @driver = nil
83
+ driver.emit(:close)
54
84
  end
55
85
 
56
86
  protected
57
87
 
88
+ attr_reader :logger
89
+
58
90
  def addr
59
91
  URI(url).host
60
92
  end
@@ -65,9 +97,9 @@ module Slack
65
97
 
66
98
  def port
67
99
  case (uri = URI(url)).scheme
68
- when 'wss'.freeze, 'https'.freeze
100
+ when 'wss', 'https'
69
101
  URI::HTTPS::DEFAULT_PORT
70
- when 'ws', 'http'.freeze
102
+ when 'ws', 'http'
71
103
  URI::HTTP::DEFAULT_PORT
72
104
  else
73
105
  uri.port
@@ -75,11 +107,7 @@ module Slack
75
107
  end
76
108
 
77
109
  def connect
78
- fail NotImplementedError, "Expected #{self.class} to implement #{__method__}."
79
- end
80
-
81
- def close(_event)
82
- @driver = nil
110
+ raise NotImplementedError, "Expected #{self.class} to implement #{__method__}."
83
111
  end
84
112
  end
85
113
  end