slack-ruby-client 0.11.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (392) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/danger.yml +19 -0
  4. data/.github/workflows/integtest.yml +25 -0
  5. data/.github/workflows/rubocop.yml +13 -0
  6. data/.github/workflows/test.yml +34 -0
  7. data/.gitignore +6 -3
  8. data/.rubocop.yml +36 -2
  9. data/.rubocop_todo.yml +186 -54
  10. data/CHANGELOG.md +156 -31
  11. data/CONTRIBUTING.md +20 -9
  12. data/Dangerfile +2 -0
  13. data/Gemfile +27 -6
  14. data/Gemfile.danger +6 -0
  15. data/LICENSE.md +1 -1
  16. data/README.md +199 -52
  17. data/RELEASING.md +2 -2
  18. data/Rakefile +2 -1
  19. data/UPGRADING.md +89 -3
  20. data/bin/commands/admin_analytics.rb +16 -0
  21. data/bin/commands/admin_apps.rb +51 -0
  22. data/bin/commands/admin_apps_approved.rb +17 -0
  23. data/bin/commands/admin_apps_requests.rb +28 -0
  24. data/bin/commands/admin_apps_restricted.rb +17 -0
  25. data/bin/commands/admin_auth_policy.rb +39 -0
  26. data/bin/commands/admin_barriers.rb +47 -0
  27. data/bin/commands/admin_conversations.rb +170 -0
  28. data/bin/commands/admin_conversations_ekm.rb +17 -0
  29. data/bin/commands/admin_conversations_restrictAccess.rb +37 -0
  30. data/bin/commands/admin_conversations_whitelist.rb +37 -0
  31. data/bin/commands/admin_emoji.rb +54 -0
  32. data/bin/commands/admin_inviteRequests.rb +36 -0
  33. data/bin/commands/admin_inviteRequests_approved.rb +16 -0
  34. data/bin/commands/admin_inviteRequests_denied.rb +16 -0
  35. data/bin/commands/admin_teams.rb +27 -0
  36. data/bin/commands/admin_teams_admins.rb +16 -0
  37. data/bin/commands/admin_teams_owners.rb +16 -0
  38. data/bin/commands/admin_teams_settings.rb +64 -0
  39. data/bin/commands/admin_usergroups.rb +48 -0
  40. data/bin/commands/admin_users.rb +98 -0
  41. data/bin/commands/admin_users_session.rb +78 -0
  42. data/bin/commands/admin_users_unsupportedVersions.rb +15 -0
  43. data/bin/commands/api.rb +1 -1
  44. data/bin/commands/apps.rb +15 -0
  45. data/bin/commands/apps_connections.rb +13 -0
  46. data/bin/commands/apps_event_authorizations.rb +16 -0
  47. data/bin/commands/apps_manifest.rb +52 -0
  48. data/bin/commands/apps_permissions.rb +1 -0
  49. data/bin/commands/apps_permissions_resources.rb +15 -0
  50. data/bin/commands/apps_permissions_scopes.rb +13 -0
  51. data/bin/commands/apps_permissions_users.rb +26 -0
  52. data/bin/commands/auth.rb +1 -0
  53. data/bin/commands/auth_teams.rb +16 -0
  54. data/bin/commands/bookmarks.rb +52 -0
  55. data/bin/commands/bots.rb +2 -0
  56. data/bin/commands/calls.rb +52 -0
  57. data/bin/commands/calls_participants.rb +25 -0
  58. data/bin/commands/channels.rb +1 -153
  59. data/bin/commands/chat.rb +57 -12
  60. data/bin/commands/chat_scheduledMessages.rb +19 -0
  61. data/bin/commands/conversations.rb +75 -4
  62. data/bin/commands/dialog.rb +1 -0
  63. data/bin/commands/dnd.rb +6 -3
  64. data/bin/commands/emoji.rb +1 -0
  65. data/bin/commands/files.rb +14 -19
  66. data/bin/commands/files_comments.rb +1 -21
  67. data/bin/commands/files_remote.rb +78 -0
  68. data/bin/commands/groups.rb +1 -159
  69. data/bin/commands/im.rb +1 -62
  70. data/bin/commands/migration.rb +2 -0
  71. data/bin/commands/mpim.rb +1 -58
  72. data/bin/commands/oauth.rb +4 -15
  73. data/bin/commands/oauth_v2.rb +29 -0
  74. data/bin/commands/openid_connect.rb +27 -0
  75. data/bin/commands/pins.rb +3 -6
  76. data/bin/commands/reactions.rb +5 -3
  77. data/bin/commands/reminders.rb +7 -0
  78. data/bin/commands/rtm.rb +7 -4
  79. data/bin/commands/search.rb +8 -3
  80. data/bin/commands/stars.rb +10 -6
  81. data/bin/commands/team.rb +6 -0
  82. data/bin/commands/team_billing.rb +13 -0
  83. data/bin/commands/team_preferences.rb +13 -0
  84. data/bin/commands/team_profile.rb +1 -0
  85. data/bin/commands/tooling_tokens.rb +14 -0
  86. data/bin/commands/usergroups.rb +7 -1
  87. data/bin/commands/usergroups_users.rb +3 -0
  88. data/bin/commands/users.rb +21 -6
  89. data/bin/commands/users_admin.rb +1 -0
  90. data/bin/commands/users_prefs.rb +1 -0
  91. data/bin/commands/users_profile.rb +7 -6
  92. data/bin/commands/views.rb +48 -0
  93. data/bin/commands/workflows.rb +38 -0
  94. data/bin/commands.rb +40 -5
  95. data/bin/slack +2 -3
  96. data/examples/hi_real_time_and_web/Gemfile +1 -0
  97. data/examples/hi_real_time_and_web/hi.rb +7 -3
  98. data/examples/{hi_real_time_async_eventmachine → hi_real_time_async_async}/Gemfile +2 -1
  99. data/examples/{hi_real_time_async_celluloid → hi_real_time_async_async}/Procfile +0 -0
  100. data/examples/{hi_real_time_async_celluloid → hi_real_time_async_async}/hi.rb +12 -7
  101. data/examples/hi_web/Gemfile +1 -0
  102. data/examples/hi_web/hi.rb +1 -0
  103. data/examples/new_ticket/Gemfile +1 -0
  104. data/examples/new_ticket/new_ticket.rb +1 -0
  105. data/lib/slack/config.rb +2 -2
  106. data/lib/slack/events/config.rb +32 -0
  107. data/lib/slack/events/request.rb +72 -0
  108. data/lib/slack/logger.rb +6 -5
  109. data/lib/slack/messages/formatting.rb +1 -1
  110. data/lib/slack/messages/message.rb +1 -4
  111. data/lib/slack/real_time/api/message.rb +3 -1
  112. data/lib/slack/real_time/api/message_id.rb +1 -0
  113. data/lib/slack/real_time/api/ping.rb +5 -2
  114. data/lib/slack/real_time/api/typing.rb +3 -1
  115. data/lib/slack/real_time/client.rb +103 -34
  116. data/lib/slack/real_time/concurrency/async.rb +138 -0
  117. data/lib/slack/real_time/concurrency.rb +2 -2
  118. data/lib/slack/real_time/config.rb +6 -10
  119. data/lib/slack/real_time/models/base.rb +1 -4
  120. data/lib/slack/real_time/models/bot.rb +1 -0
  121. data/lib/slack/real_time/models/channel.rb +1 -0
  122. data/lib/slack/real_time/models/group.rb +1 -0
  123. data/lib/slack/real_time/models/im.rb +1 -0
  124. data/lib/slack/real_time/models/team.rb +1 -0
  125. data/lib/slack/real_time/models/user.rb +1 -0
  126. data/lib/slack/real_time/models.rb +1 -0
  127. data/lib/slack/real_time/socket.rb +45 -17
  128. data/lib/slack/real_time/stores/base.rb +5 -7
  129. data/lib/slack/real_time/stores/starter.rb +27 -3
  130. data/lib/slack/real_time/stores/store.rb +43 -25
  131. data/lib/slack/real_time/stores.rb +1 -0
  132. data/lib/slack/version.rb +2 -1
  133. data/lib/slack/web/api/endpoints/admin_analytics.rb +28 -0
  134. data/lib/slack/web/api/endpoints/admin_apps.rb +78 -0
  135. data/lib/slack/web/api/endpoints/admin_apps_approved.rb +35 -0
  136. data/lib/slack/web/api/endpoints/admin_apps_requests.rb +51 -0
  137. data/lib/slack/web/api/endpoints/admin_apps_restricted.rb +35 -0
  138. data/lib/slack/web/api/endpoints/admin_auth_policy.rb +72 -0
  139. data/lib/slack/web/api/endpoints/admin_barriers.rb +82 -0
  140. data/lib/slack/web/api/endpoints/admin_conversations.rb +262 -0
  141. data/lib/slack/web/api/endpoints/admin_conversations_ekm.rb +35 -0
  142. data/lib/slack/web/api/endpoints/admin_conversations_restrictAccess.rb +61 -0
  143. data/lib/slack/web/api/endpoints/admin_conversations_whitelist.rb +64 -0
  144. data/lib/slack/web/api/endpoints/admin_emoji.rb +88 -0
  145. data/lib/slack/web/api/endpoints/admin_inviteRequests.rb +61 -0
  146. data/lib/slack/web/api/endpoints/admin_inviteRequests_approved.rb +33 -0
  147. data/lib/slack/web/api/endpoints/admin_inviteRequests_denied.rb +33 -0
  148. data/lib/slack/web/api/endpoints/admin_teams.rb +50 -0
  149. data/lib/slack/web/api/endpoints/admin_teams_admins.rb +34 -0
  150. data/lib/slack/web/api/endpoints/admin_teams_owners.rb +34 -0
  151. data/lib/slack/web/api/endpoints/admin_teams_settings.rb +99 -0
  152. data/lib/slack/web/api/endpoints/admin_usergroups.rb +77 -0
  153. data/lib/slack/web/api/endpoints/admin_users.rb +163 -0
  154. data/lib/slack/web/api/endpoints/admin_users_session.rb +122 -0
  155. data/lib/slack/web/api/endpoints/admin_users_unsupportedVersions.rb +25 -0
  156. data/lib/slack/web/api/endpoints/api.rb +2 -3
  157. data/lib/slack/web/api/endpoints/apps.rb +27 -0
  158. data/lib/slack/web/api/endpoints/apps_connections.rb +21 -0
  159. data/lib/slack/web/api/endpoints/apps_event_authorizations.rb +34 -0
  160. data/lib/slack/web/api/endpoints/apps_manifest.rb +77 -0
  161. data/lib/slack/web/api/endpoints/apps_permissions.rb +1 -0
  162. data/lib/slack/web/api/endpoints/apps_permissions_resources.rb +31 -0
  163. data/lib/slack/web/api/endpoints/apps_permissions_scopes.rb +21 -0
  164. data/lib/slack/web/api/endpoints/apps_permissions_users.rb +50 -0
  165. data/lib/slack/web/api/endpoints/auth.rb +2 -1
  166. data/lib/slack/web/api/endpoints/auth_teams.rb +33 -0
  167. data/lib/slack/web/api/endpoints/bookmarks.rb +86 -0
  168. data/lib/slack/web/api/endpoints/bots.rb +4 -1
  169. data/lib/slack/web/api/endpoints/calls.rb +83 -0
  170. data/lib/slack/web/api/endpoints/calls_participants.rb +42 -0
  171. data/lib/slack/web/api/endpoints/channels.rb +2 -243
  172. data/lib/slack/web/api/endpoints/chat.rb +145 -46
  173. data/lib/slack/web/api/endpoints/chat_scheduledMessages.rb +40 -0
  174. data/lib/slack/web/api/endpoints/conversations.rb +152 -39
  175. data/lib/slack/web/api/endpoints/dialog.rb +3 -2
  176. data/lib/slack/web/api/endpoints/dnd.rb +9 -4
  177. data/lib/slack/web/api/endpoints/emoji.rb +1 -0
  178. data/lib/slack/web/api/endpoints/files.rb +35 -28
  179. data/lib/slack/web/api/endpoints/files_comments.rb +2 -34
  180. data/lib/slack/web/api/endpoints/files_remote.rb +127 -0
  181. data/lib/slack/web/api/endpoints/groups.rb +1 -243
  182. data/lib/slack/web/api/endpoints/im.rb +1 -101
  183. data/lib/slack/web/api/endpoints/migration.rb +5 -2
  184. data/lib/slack/web/api/endpoints/mpim.rb +1 -86
  185. data/lib/slack/web/api/endpoints/oauth.rb +8 -30
  186. data/lib/slack/web/api/endpoints/oauth_v2.rb +48 -0
  187. data/lib/slack/web/api/endpoints/openid_connect.rb +42 -0
  188. data/lib/slack/web/api/endpoints/pins.rb +8 -15
  189. data/lib/slack/web/api/endpoints/reactions.rb +29 -18
  190. data/lib/slack/web/api/endpoints/reminders.rb +18 -5
  191. data/lib/slack/web/api/endpoints/rtm.rb +14 -9
  192. data/lib/slack/web/api/endpoints/search.rb +30 -15
  193. data/lib/slack/web/api/endpoints/stars.rb +23 -10
  194. data/lib/slack/web/api/endpoints/team.rb +15 -4
  195. data/lib/slack/web/api/endpoints/team_billing.rb +21 -0
  196. data/lib/slack/web/api/endpoints/team_preferences.rb +21 -0
  197. data/lib/slack/web/api/endpoints/team_profile.rb +2 -1
  198. data/lib/slack/web/api/endpoints/tooling_tokens.rb +24 -0
  199. data/lib/slack/web/api/endpoints/usergroups.rb +27 -16
  200. data/lib/slack/web/api/endpoints/usergroups_users.rb +10 -5
  201. data/lib/slack/web/api/endpoints/users.rb +44 -17
  202. data/lib/slack/web/api/endpoints/users_admin.rb +1 -0
  203. data/lib/slack/web/api/endpoints/users_prefs.rb +1 -0
  204. data/lib/slack/web/api/endpoints/users_profile.rb +9 -8
  205. data/lib/slack/web/api/endpoints/views.rb +97 -0
  206. data/lib/slack/web/api/endpoints/workflows.rb +61 -0
  207. data/lib/slack/web/api/endpoints.rb +80 -12
  208. data/lib/slack/web/api/error.rb +1 -0
  209. data/lib/slack/web/api/errors/server_error.rb +37 -0
  210. data/lib/slack/web/api/errors/slack_error.rb +14 -1
  211. data/lib/slack/web/api/errors/too_many_requests_error.rb +2 -4
  212. data/lib/slack/web/api/errors.rb +1066 -0
  213. data/lib/slack/web/api/mixins/{channels.id.rb → conversations.id.rb} +4 -5
  214. data/lib/slack/web/api/mixins/ids.id.rb +3 -2
  215. data/lib/slack/web/api/mixins/users.id.rb +2 -3
  216. data/lib/slack/web/api/mixins/users.search.rb +1 -0
  217. data/lib/slack/web/api/mixins.rb +2 -2
  218. data/lib/slack/web/api/patches/chat.1.patch +70 -0
  219. data/lib/slack/web/api/patches/views.1.view-json.patch +40 -0
  220. data/lib/slack/web/api/patches/views.1.views-published.patch +16 -0
  221. data/lib/slack/web/api/templates/command.erb +1 -0
  222. data/lib/slack/web/api/templates/commands.erb +1 -0
  223. data/lib/slack/web/api/templates/endpoints.erb +2 -2
  224. data/lib/slack/web/api/templates/errors.erb +20 -0
  225. data/lib/slack/web/api/templates/method.erb +5 -1
  226. data/lib/slack/web/api/templates/method_spec.erb +2 -1
  227. data/lib/slack/web/client.rb +2 -1
  228. data/lib/slack/web/config.rb +3 -0
  229. data/lib/slack/web/faraday/connection.rb +24 -20
  230. data/lib/slack/web/faraday/request.rb +5 -1
  231. data/lib/slack/web/faraday/response/raise_error.rb +14 -7
  232. data/lib/slack/web/faraday/response/wrap_error.rb +24 -0
  233. data/lib/slack/web/pagination/cursor.rb +7 -7
  234. data/lib/slack-ruby-client.rb +12 -5
  235. data/lib/slack.rb +1 -0
  236. data/lib/slack_ruby_client.rb +1 -0
  237. data/lib/tasks/git.rake +1 -0
  238. data/lib/tasks/real_time.rake +16 -8
  239. data/lib/tasks/update.rake +1 -0
  240. data/lib/tasks/web.rake +39 -10
  241. data/screenshots/create-app.png +0 -0
  242. data/slack-ruby-client.gemspec +7 -12
  243. data/spec/fixtures/slack/web/429_error.yml +50 -54
  244. data/spec/fixtures/slack/web/auth_test_error.yml +51 -18
  245. data/spec/fixtures/slack/web/auth_test_success.yml +50 -26
  246. data/spec/fixtures/slack/web/conversations_info.yml +167 -0
  247. data/spec/fixtures/slack/web/conversations_setTopic.yml +84 -0
  248. data/spec/fixtures/slack/web/conversations_setTopic_one_page.yml +172 -0
  249. data/spec/fixtures/slack/web/conversations_setTopic_paginated.yml +253 -0
  250. data/spec/fixtures/slack/web/paginated_users_list.yml +501 -69
  251. data/spec/fixtures/slack/web/rtm_connect.yml +267 -30
  252. data/spec/fixtures/slack/web/rtm_start.yml +771 -60
  253. data/spec/fixtures/slack/web/users_info.yml +153 -69
  254. data/spec/fixtures/slack/web/users_list.yml +102 -41
  255. data/spec/fixtures/slack/web/views_open_error.yml +83 -0
  256. data/spec/integration/integration_spec.rb +116 -48
  257. data/spec/slack/config_spec.rb +2 -0
  258. data/spec/slack/events/config_spec.rb +33 -0
  259. data/spec/slack/events/request_spec.rb +184 -0
  260. data/spec/slack/messages/formatting_spec.rb +25 -14
  261. data/spec/slack/real_time/api/message_spec.rb +6 -1
  262. data/spec/slack/real_time/api/ping_spec.rb +2 -0
  263. data/spec/slack/real_time/api/typing_spec.rb +5 -1
  264. data/spec/slack/real_time/client_spec.rb +258 -62
  265. data/spec/slack/real_time/concurrency/it_behaves_like_a_realtime_socket.rb +2 -0
  266. data/spec/slack/real_time/concurrency/with_concurrency_spec.rb +10 -0
  267. data/spec/slack/real_time/concurrency/without_concurrency_spec.rb +10 -0
  268. data/spec/slack/real_time/event_handlers/bot_spec.rb +3 -2
  269. data/spec/slack/real_time/event_handlers/channel_spec.rb +14 -11
  270. data/spec/slack/real_time/event_handlers/event_handlers_spec.rb +2 -1
  271. data/spec/slack/real_time/event_handlers/group_spec.rb +6 -5
  272. data/spec/slack/real_time/event_handlers/im_spec.rb +10 -9
  273. data/spec/slack/real_time/event_handlers/team_spec.rb +3 -1
  274. data/spec/slack/real_time/event_handlers/user_spec.rb +3 -2
  275. data/spec/slack/real_time/rtm_connect_spec.rb +2 -1
  276. data/spec/slack/real_time/rtm_start_spec.rb +2 -1
  277. data/spec/slack/real_time/store_spec.rb +4 -3
  278. data/spec/slack/slack_spec.rb +42 -8
  279. data/spec/slack/version_spec.rb +2 -1
  280. data/spec/slack/web/api/endpoints/admin_analytics_spec.rb +13 -0
  281. data/spec/slack/web/api/endpoints/admin_apps_approved_spec.rb +8 -0
  282. data/spec/slack/web/api/endpoints/admin_apps_requests_spec.rb +13 -0
  283. data/spec/slack/web/api/endpoints/admin_apps_restricted_spec.rb +8 -0
  284. data/spec/slack/web/api/endpoints/admin_apps_spec.rb +18 -0
  285. data/spec/slack/web/api/endpoints/admin_auth_policy_spec.rb +35 -0
  286. data/spec/slack/web/api/endpoints/admin_barriers_spec.rb +38 -0
  287. data/spec/slack/web/api/endpoints/admin_conversations_ekm_spec.rb +8 -0
  288. data/spec/slack/web/api/endpoints/admin_conversations_restrictAccess_spec.rb +32 -0
  289. data/spec/slack/web/api/endpoints/admin_conversations_spec.rb +98 -0
  290. data/spec/slack/web/api/endpoints/admin_emoji_spec.rb +37 -0
  291. data/spec/slack/web/api/endpoints/admin_inviteRequests_approved_spec.rb +8 -0
  292. data/spec/slack/web/api/endpoints/admin_inviteRequests_denied_spec.rb +8 -0
  293. data/spec/slack/web/api/endpoints/admin_inviteRequests_spec.rb +18 -0
  294. data/spec/slack/web/api/endpoints/admin_teams_admins_spec.rb +13 -0
  295. data/spec/slack/web/api/endpoints/admin_teams_owners_spec.rb +13 -0
  296. data/spec/slack/web/api/endpoints/admin_teams_settings_spec.rb +53 -0
  297. data/spec/slack/web/api/endpoints/admin_teams_spec.rb +16 -0
  298. data/spec/slack/web/api/endpoints/admin_usergroups_spec.rb +37 -0
  299. data/spec/slack/web/api/endpoints/admin_users_session_spec.rb +41 -0
  300. data/spec/slack/web/api/endpoints/admin_users_spec.rb +67 -0
  301. data/spec/slack/web/api/endpoints/admin_users_unsupportedVersions_spec.rb +8 -0
  302. data/spec/slack/web/api/endpoints/api_spec.rb +1 -0
  303. data/spec/slack/web/api/endpoints/apps_connections_spec.rb +8 -0
  304. data/spec/slack/web/api/endpoints/apps_event_authorizations_spec.rb +13 -0
  305. data/spec/slack/web/api/endpoints/apps_manifest_spec.rb +36 -0
  306. data/spec/slack/web/api/endpoints/apps_spec.rb +16 -0
  307. data/spec/slack/web/api/endpoints/auth_teams_spec.rb +8 -0
  308. data/spec/slack/web/api/endpoints/bookmarks_spec.rb +40 -0
  309. data/spec/slack/web/api/endpoints/bots_spec.rb +1 -0
  310. data/spec/slack/web/api/endpoints/calls_participants_spec.rb +24 -0
  311. data/spec/slack/web/api/endpoints/calls_spec.rb +31 -0
  312. data/spec/slack/web/api/endpoints/chat_scheduledMessages_spec.rb +8 -0
  313. data/spec/slack/web/api/endpoints/custom_specs/auth_spec.rb +9 -7
  314. data/spec/slack/web/api/endpoints/custom_specs/chat_spec.rb +131 -39
  315. data/spec/slack/web/api/endpoints/custom_specs/conversations_spec.rb +13 -0
  316. data/spec/slack/web/api/endpoints/custom_specs/dialog_spec.rb +16 -6
  317. data/spec/slack/web/api/endpoints/custom_specs/users_spec.rb +8 -3
  318. data/spec/slack/web/api/endpoints/custom_specs/views_spec.rb +103 -0
  319. data/spec/slack/web/api/endpoints/dnd_spec.rb +4 -3
  320. data/spec/slack/web/api/endpoints/emoji_spec.rb +1 -0
  321. data/spec/slack/web/api/endpoints/files_comments_spec.rb +3 -21
  322. data/spec/slack/web/api/endpoints/files_remote_spec.rb +24 -0
  323. data/spec/slack/web/api/endpoints/files_spec.rb +5 -4
  324. data/spec/slack/web/api/endpoints/migration_spec.rb +1 -0
  325. data/spec/slack/web/api/endpoints/oauth_spec.rb +1 -22
  326. data/spec/slack/web/api/endpoints/oauth_v2_spec.rb +16 -0
  327. data/spec/slack/web/api/endpoints/openid_connect_spec.rb +8 -0
  328. data/spec/slack/web/api/endpoints/pins_spec.rb +1 -0
  329. data/spec/slack/web/api/endpoints/reactions_spec.rb +8 -1
  330. data/spec/slack/web/api/endpoints/reminders_spec.rb +3 -2
  331. data/spec/slack/web/api/endpoints/rtm_spec.rb +1 -0
  332. data/spec/slack/web/api/endpoints/search_spec.rb +1 -0
  333. data/spec/slack/web/api/endpoints/stars_spec.rb +1 -0
  334. data/spec/slack/web/api/endpoints/team_billing_spec.rb +8 -0
  335. data/spec/slack/web/api/endpoints/team_preferences_spec.rb +8 -0
  336. data/spec/slack/web/api/endpoints/team_profile_spec.rb +1 -0
  337. data/spec/slack/web/api/endpoints/team_spec.rb +1 -0
  338. data/spec/slack/web/api/endpoints/tooling_tokens_spec.rb +13 -0
  339. data/spec/slack/web/api/endpoints/usergroups_spec.rb +1 -0
  340. data/spec/slack/web/api/endpoints/usergroups_users_spec.rb +3 -2
  341. data/spec/slack/web/api/endpoints/users_admin_spec.rb +1 -0
  342. data/spec/slack/web/api/endpoints/users_prefs_spec.rb +1 -0
  343. data/spec/slack/web/api/endpoints/users_profile_spec.rb +1 -0
  344. data/spec/slack/web/api/endpoints/workflows_spec.rb +26 -0
  345. data/spec/slack/web/api/error_spec.rb +7 -7
  346. data/spec/slack/web/api/errors/slack_error_spec.rb +26 -7
  347. data/spec/slack/web/api/mixins/conversations_list_spec.rb +21 -0
  348. data/spec/slack/web/api/mixins/conversations_spec.rb +43 -0
  349. data/spec/slack/web/api/mixins/users_spec.rb +25 -14
  350. data/spec/slack/web/api/pagination/cursor_spec.rb +43 -15
  351. data/spec/slack/web/client_spec.rb +186 -19
  352. data/spec/slack/web/faraday/request_spec.rb +80 -0
  353. data/spec/slack/web/faraday/response/raise_error_spec.rb +48 -12
  354. data/spec/spec_helper.rb +9 -2
  355. data/spec/support/queue_with_timeout.rb +5 -4
  356. data/spec/support/real_time/concurrency/mock.rb +1 -0
  357. data/spec/support/real_time/connected_client.rb +6 -6
  358. data/spec/support/real_time/event.rb +1 -0
  359. data/spec/support/token.rb +1 -0
  360. data/spec/support/vcr.rb +37 -1
  361. metadata +177 -231
  362. data/.travis.yml +0 -30
  363. data/examples/hi_real_time/Gemfile +0 -5
  364. data/examples/hi_real_time/hi.gif +0 -0
  365. data/examples/hi_real_time/hi.rb +0 -37
  366. data/examples/hi_real_time_async_celluloid/Gemfile +0 -6
  367. data/examples/hi_real_time_async_eventmachine/Procfile +0 -2
  368. data/examples/hi_real_time_async_eventmachine/hi.rb +0 -36
  369. data/lib/slack/real_time/concurrency/celluloid.rb +0 -117
  370. data/lib/slack/real_time/concurrency/eventmachine.rb +0 -60
  371. data/lib/slack/web/api/mixins/channels.id.json +0 -20
  372. data/lib/slack/web/api/mixins/groups.id.json +0 -20
  373. data/lib/slack/web/api/mixins/groups.id.rb +0 -26
  374. data/lib/slack/web/api/patches/chat.1.text-attachments-required.patch +0 -13
  375. data/lib/slack/web/api/patches/chat.2.attachments-json.patch +0 -17
  376. data/lib/slack/web/api/patches/chat.3.update-attachments-support.patch +0 -21
  377. data/lib/slack/web/api/patches/chat.4.postEphemeral-attachments-support.patch +0 -17
  378. data/screenshots/register-bot.png +0 -0
  379. data/spec/fixtures/slack/web/503_error.yml +0 -14
  380. data/spec/fixtures/slack/web/channels_info.yml +0 -46
  381. data/spec/fixtures/slack/web/groups_info.yml +0 -43
  382. data/spec/slack/real_time/concurrency/celluloid_spec.rb +0 -62
  383. data/spec/slack/real_time/concurrency/eventmachine_spec.rb +0 -47
  384. data/spec/slack/web/api/endpoints/apps_permissions_spec.rb +0 -15
  385. data/spec/slack/web/api/endpoints/conversations_spec.rb +0 -100
  386. data/spec/slack/web/api/endpoints/custom_specs/channels_spec.rb +0 -11
  387. data/spec/slack/web/api/endpoints/custom_specs/groups_spec.rb +0 -11
  388. data/spec/slack/web/api/endpoints/im_spec.rb +0 -38
  389. data/spec/slack/web/api/endpoints/mpim_spec.rb +0 -38
  390. data/spec/slack/web/api/errors/service_unavailable_spec.rb +0 -14
  391. data/spec/slack/web/api/mixins/channels_spec.rb +0 -31
  392. data/spec/slack/web/api/mixins/groups_spec.rb +0 -31
data/lib/slack/config.rb CHANGED
@@ -1,9 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module Config
3
4
  extend self
4
5
 
5
- attr_accessor :token
6
- attr_accessor :logger
6
+ attr_accessor :token, :logger
7
7
 
8
8
  def reset
9
9
  self.token = nil
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ module Slack
3
+ module Events
4
+ module Config
5
+ extend self
6
+
7
+ ATTRIBUTES = %i[
8
+ signing_secret
9
+ signature_expires_in
10
+ ].freeze
11
+
12
+ attr_accessor(*Config::ATTRIBUTES)
13
+
14
+ def reset
15
+ self.signing_secret = ENV['SLACK_SIGNING_SECRET']
16
+ self.signature_expires_in = 5 * 60
17
+ end
18
+ end
19
+
20
+ class << self
21
+ def configure
22
+ block_given? ? yield(Config) : Config
23
+ end
24
+
25
+ def config
26
+ Config
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ Slack::Events::Config.reset
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+ module Slack
3
+ module Events
4
+ class Request
5
+ class MissingSigningSecret < StandardError; end
6
+
7
+ class TimestampExpired < StandardError; end
8
+
9
+ class InvalidSignature < StandardError; end
10
+
11
+ attr_reader :http_request,
12
+ :signing_secret,
13
+ :signature_expires_in
14
+
15
+ def initialize(http_request, options = {})
16
+ @http_request = http_request
17
+ @signing_secret = options[:signing_secret] || Slack::Events.config.signing_secret
18
+ @signature_expires_in =
19
+ options[:signature_expires_in] || Slack::Events.config.signature_expires_in
20
+ end
21
+
22
+ # Request timestamp.
23
+ def timestamp
24
+ @timestamp ||= http_request.get_header('HTTP_X_SLACK_REQUEST_TIMESTAMP')
25
+ end
26
+
27
+ # The signature is created by combining the signing secret with the body of the request
28
+ # Slack is sending using a standard HMAC-SHA256 keyed hash.
29
+ def signature
30
+ @signature ||= http_request.get_header('HTTP_X_SLACK_SIGNATURE')
31
+ end
32
+
33
+ # Signature version.
34
+ def version
35
+ 'v0'
36
+ end
37
+
38
+ # Request body.
39
+ def body
40
+ @body ||= begin
41
+ body = http_request.body.read
42
+ http_request.body.rewind
43
+ body
44
+ end
45
+ end
46
+
47
+ # Returns true if the signature coming from Slack has expired.
48
+ def expired?
49
+ timestamp.nil? || (Time.now.to_i - timestamp.to_i).abs > signature_expires_in
50
+ end
51
+
52
+ # Returns true if the signature coming from Slack is valid.
53
+ def valid?
54
+ raise MissingSigningSecret unless signing_secret
55
+
56
+ digest = OpenSSL::Digest.new('SHA256')
57
+ signature_basestring = [version, timestamp, body].join(':')
58
+ hex_hash = OpenSSL::HMAC.hexdigest(digest, signing_secret, signature_basestring)
59
+ computed_signature = [version, hex_hash].join('=')
60
+ computed_signature == signature
61
+ end
62
+
63
+ # Validates the request signature and its expiration.
64
+ def verify!
65
+ raise TimestampExpired if expired?
66
+ raise InvalidSignature unless valid?
67
+
68
+ true
69
+ end
70
+ end
71
+ end
72
+ end
data/lib/slack/logger.rb CHANGED
@@ -1,13 +1,14 @@
1
+ # frozen_string_literal: true
1
2
  require 'logger'
2
3
 
3
4
  module Slack
4
5
  class Logger < ::Logger
5
6
  def self.default
6
- @logger ||= begin
7
- logger = new STDOUT
8
- logger.level = Logger::WARN
9
- logger
10
- end
7
+ return @default if @default
8
+
9
+ logger = new STDOUT
10
+ logger.level = Logger::WARN
11
+ @default = logger
11
12
  end
12
13
  end
13
14
  end
@@ -1,4 +1,4 @@
1
-
1
+ # frozen_string_literal: true
2
2
  module Slack
3
3
  module Messages
4
4
  module Formatting
@@ -1,10 +1,7 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module Messages
3
4
  class Message < Hashie::Mash
4
- def presence
5
- super['presence']
6
- end
7
-
8
5
  def to_s
9
6
  keys.sort_by(&:to_s).map do |key|
10
7
  "#{key}=#{self[key]}"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Api
@@ -6,7 +7,8 @@ module Slack
6
7
  # Sends a message to a channel.
7
8
  #
8
9
  # @option options [channel] :channel
9
- # Channel to send message to. Can be a public channel, private group or IM channel. Can be an encoded ID, or a name.
10
+ # Channel to send message to. Can be a public channel, private group or IM channel.
11
+ # Can be an encoded ID, or a name.
10
12
  # @option options [Object] :text
11
13
  # Text of the message to send. See below for an explanation of formatting.
12
14
  def message(options = {})
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Api
@@ -1,10 +1,13 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Api
4
5
  module Ping
5
6
  #
6
- # Clients should try to quickly detect disconnections, even in idle periods, so that users can easily tell the
7
- # difference between being disconnected and everyone being quiet. Not all web browsers support the WebSocket
7
+ # Clients should try to quickly detect disconnections, even in idle periods, so that users
8
+ # can easily tell the
9
+ # difference between being disconnected and everyone being quiet. Not all web browsers
10
+ # support the WebSocket
8
11
  # ping spec, so the RTM protocol also supports ping/pong messages.
9
12
  #
10
13
  def ping(options = {})
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Slack
2
3
  module RealTime
3
4
  module Api
@@ -6,7 +7,8 @@ module Slack
6
7
  # Send a typing indicator to indicate that the user is currently writing a message.
7
8
  #
8
9
  # @option options [channel] :channel
9
- # Channel to send message to. Can be a public channel, private group or IM channel. Can be an encoded ID, or a name.
10
+ # Channel to send message to. Can be a public channel, private group or IM channel.
11
+ # Can be an encoded ID, or a name.
10
12
  def typing(options = {})
11
13
  throw ArgumentError.new('Required arguments :channel missing') if options[:channel].nil?
12
14
  send_json({ type: 'typing', id: next_id }.merge(options))
@@ -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 = {})
@@ -35,7 +33,7 @@ module Slack
35
33
 
36
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
 
@@ -46,26 +44,27 @@ module Slack
46
44
 
47
45
  # Start RealTime client and block until it disconnects.
48
46
  def start!(&block)
49
- @callback = block if block_given?
50
- @socket = build_socket
47
+ @callback = block if block
48
+ build_socket
51
49
  @socket.start_sync(self)
52
50
  end
53
51
 
54
52
  # Start RealTime client and return immediately.
55
53
  # The RealTime::Client will run in the background.
56
54
  def start_async(&block)
57
- @callback = block if block_given?
58
- @socket = build_socket
55
+ @callback = block if block
56
+ build_socket
59
57
  @socket.start_async(self)
60
58
  end
61
59
 
62
60
  def stop!
63
61
  raise ClientNotStartedError unless started?
64
- @socket.disconnect! if @socket
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,105 @@ 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
174
  raise ClientAlreadyStartedError if started?
175
+
110
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)
115
181
  end
116
182
 
117
183
  def rtm_start_method
@@ -133,23 +199,22 @@ module Slack
133
199
  end
134
200
 
135
201
  attr_reader :callbacks
202
+
136
203
  def socket_class
137
204
  concurrency::Socket
138
205
  end
139
206
 
140
207
  def send_json(data)
141
208
  raise ClientNotStartedError unless started?
142
- logger.debug("#{self.class}##{__method__}") { data }
209
+
210
+ logger.debug("#{self}##{__method__}") { data }
143
211
  @socket.send_data(data.to_json)
144
212
  end
145
213
 
146
- def open(_event); end
214
+ def open_event(_event); end
147
215
 
148
216
  def close(_event)
149
- socket = @socket
150
- @socket = nil
151
-
152
- [socket, socket_class].each do |s|
217
+ [@socket, socket_class].each do |s|
153
218
  s.close if s.respond_to?(:close)
154
219
  end
155
220
  end
@@ -157,50 +222,54 @@ module Slack
157
222
  def callback(event, type)
158
223
  callbacks = self.callbacks[type.to_s]
159
224
  return false unless callbacks
225
+
160
226
  callbacks.each do |c|
161
227
  c.call(event)
162
228
  end
163
229
  true
164
230
  rescue StandardError => e
165
- logger.error e
231
+ logger.error("#{self}##{__method__}") { e }
166
232
  false
167
233
  end
168
234
 
169
235
  def dispatch(event)
170
236
  return false unless event.data
237
+
171
238
  data = Slack::Messages::Message.new(JSON.parse(event.data))
172
239
  type = data.type
173
240
  return false unless type
241
+
174
242
  type = type.to_s
175
- logger.debug("#{self.class}##{__method__}") { data.to_s }
243
+ logger.debug("#{self}##{__method__}") { data.to_s }
176
244
  run_handlers(type, data) if @store
177
245
  run_callbacks(type, data)
178
246
  rescue StandardError => e
179
- logger.error e
247
+ logger.error("#{self}##{__method__}") { e }
180
248
  false
181
249
  end
182
250
 
183
251
  def run_handlers(type, data)
252
+ return unless store.class.events
253
+
184
254
  handlers = store.class.events[type.to_s]
185
- if handlers
186
- handlers.each do |handler|
187
- store.instance_exec(data, &handler)
188
- end
255
+ handlers&.each do |handler|
256
+ store.instance_exec(data, &handler)
189
257
  end
190
258
  rescue StandardError => e
191
- logger.error e
259
+ logger.error("#{self}##{__method__}") { e }
192
260
  false
193
261
  end
194
262
 
195
263
  def run_callbacks(type, data)
196
264
  callbacks = self.callbacks[type]
197
265
  return false unless callbacks
266
+
198
267
  callbacks.each do |c|
199
268
  c.call(data)
200
269
  end
201
270
  true
202
271
  rescue StandardError => e
203
- logger.error e
272
+ logger.error("#{self}##{__method__}") { e }
204
273
  false
205
274
  end
206
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
@@ -16,7 +17,8 @@ module Slack
16
17
  logger
17
18
  ].freeze
18
19
 
19
- attr_accessor(*Config::ATTRIBUTES)
20
+ attr_accessor(*Config::ATTRIBUTES - [:concurrency])
21
+ attr_writer :concurrency
20
22
 
21
23
  def reset
22
24
  self.websocket_ping = 30
@@ -36,15 +38,9 @@ module Slack
36
38
  private
37
39
 
38
40
  def detect_concurrency
39
- %i[Eventmachine Celluloid].each do |concurrency|
40
- begin
41
- return Slack::RealTime::Concurrency.const_get(concurrency)
42
- rescue LoadError, NameError
43
- false # could not be loaded, missing dependencies
44
- end
45
- end
46
-
47
- raise 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.'
48
44
  end
49
45
  end
50
46
 
@@ -1,11 +1,8 @@
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
8
-
9
6
  # see https://github.com/intridea/hashie/issues/394
10
7
  def log_built_in_message(*); end
11
8
  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