slack-ruby-client 0.11.0 → 2.7.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 (403) hide show
  1. checksums.yaml +5 -5
  2. data/.coveralls.yml +2 -0
  3. data/.github/FUNDING.yml +2 -0
  4. data/.github/dependabot.yml +6 -0
  5. data/.github/workflows/integration_test.yml +45 -0
  6. data/.github/workflows/lint.yml +14 -0
  7. data/.github/workflows/pr_lint.yml +21 -0
  8. data/.github/workflows/test.yml +56 -0
  9. data/.github/workflows/update_api.yml +81 -0
  10. data/.gitignore +7 -3
  11. data/.rubocop.yml +40 -2
  12. data/.rubocop_todo.yml +209 -55
  13. data/.ruby-version +1 -0
  14. data/CHANGELOG.md +257 -30
  15. data/CONTRIBUTING.md +44 -29
  16. data/Dangerfile +2 -0
  17. data/Gemfile +28 -6
  18. data/Gemfile.danger +6 -0
  19. data/LICENSE.md +1 -1
  20. data/README.md +473 -134
  21. data/RELEASING.md +2 -2
  22. data/Rakefile +2 -1
  23. data/SECURITY.md +9 -0
  24. data/UPGRADING.md +117 -3
  25. data/bin/commands/admin_analytics.rb +22 -0
  26. data/bin/commands/admin_apps.rb +57 -0
  27. data/bin/commands/admin_apps_activities.rb +32 -0
  28. data/bin/commands/admin_apps_approved.rb +24 -0
  29. data/bin/commands/admin_apps_config.rb +31 -0
  30. data/bin/commands/admin_apps_requests.rb +35 -0
  31. data/bin/commands/admin_apps_restricted.rb +24 -0
  32. data/bin/commands/admin_audit_anomaly_allow.rb +29 -0
  33. data/bin/commands/admin_auth_policy.rb +45 -0
  34. data/bin/commands/admin_barriers.rb +53 -0
  35. data/bin/commands/admin_conversations.rb +260 -0
  36. data/bin/commands/admin_conversations_ekm.rb +23 -0
  37. data/bin/commands/admin_conversations_restrictAccess.rb +43 -0
  38. data/bin/commands/admin_emoji.rb +60 -0
  39. data/bin/commands/admin_functions.rb +23 -0
  40. data/bin/commands/admin_functions_permissions.rb +31 -0
  41. data/bin/commands/admin_inviteRequests.rb +42 -0
  42. data/bin/commands/admin_inviteRequests_approved.rb +22 -0
  43. data/bin/commands/admin_inviteRequests_denied.rb +22 -0
  44. data/bin/commands/admin_roles.rb +46 -0
  45. data/bin/commands/admin_teams.rb +33 -0
  46. data/bin/commands/admin_teams_admins.rb +22 -0
  47. data/bin/commands/admin_teams_owners.rb +22 -0
  48. data/bin/commands/admin_teams_settings.rb +70 -0
  49. data/bin/commands/admin_usergroups.rb +54 -0
  50. data/bin/commands/admin_users.rb +106 -0
  51. data/bin/commands/admin_users_session.rb +84 -0
  52. data/bin/commands/admin_users_unsupportedVersions.rb +21 -0
  53. data/bin/commands/admin_workflows.rb +42 -0
  54. data/bin/commands/admin_workflows_collaborators.rb +31 -0
  55. data/bin/commands/admin_workflows_permissions.rb +21 -0
  56. data/bin/commands/admin_workflows_triggers_types_permissions.rb +31 -0
  57. data/bin/commands/api.rb +15 -9
  58. data/bin/commands/apps.rb +21 -0
  59. data/bin/commands/apps_activities.rb +32 -0
  60. data/bin/commands/apps_auth_external.rb +32 -0
  61. data/bin/commands/apps_connections.rb +19 -0
  62. data/bin/commands/apps_datastore.rb +116 -0
  63. data/bin/commands/apps_event_authorizations.rb +22 -0
  64. data/bin/commands/apps_manifest.rb +58 -0
  65. data/bin/commands/assistant_search.rb +27 -0
  66. data/bin/commands/assistant_threads.rb +45 -0
  67. data/bin/commands/auth.rb +22 -15
  68. data/bin/commands/auth_teams.rb +22 -0
  69. data/bin/commands/bookmarks.rb +60 -0
  70. data/bin/commands/bots.rb +16 -8
  71. data/bin/commands/calls.rb +58 -0
  72. data/bin/commands/calls_participants.rb +31 -0
  73. data/bin/commands/canvases.rb +41 -0
  74. data/bin/commands/canvases_access.rb +34 -0
  75. data/bin/commands/canvases_sections.rb +21 -0
  76. data/bin/commands/chat.rb +158 -99
  77. data/bin/commands/chat_scheduledMessages.rb +25 -0
  78. data/bin/commands/conversations.rb +241 -157
  79. data/bin/commands/conversations_canvases.rb +22 -0
  80. data/bin/commands/conversations_externalInvitePermissions.rb +22 -0
  81. data/bin/commands/conversations_requestSharedInvite.rb +48 -0
  82. data/bin/commands/dialog.rb +16 -9
  83. data/bin/commands/dnd.rb +47 -38
  84. data/bin/commands/emoji.rb +15 -7
  85. data/bin/commands/files.rb +113 -87
  86. data/bin/commands/files_comments.rb +16 -30
  87. data/bin/commands/files_remote.rb +84 -0
  88. data/bin/commands/functions.rb +31 -0
  89. data/bin/commands/functions_distributions_permissions.rb +61 -0
  90. data/bin/commands/functions_workflows_steps.rb +23 -0
  91. data/bin/commands/functions_workflows_steps_responses.rb +23 -0
  92. data/bin/commands/migration.rb +17 -9
  93. data/bin/commands/oauth.rb +19 -24
  94. data/bin/commands/oauth_v2.rb +35 -0
  95. data/bin/commands/openid_connect.rb +33 -0
  96. data/bin/commands/pins.rb +33 -30
  97. data/bin/commands/reactions.rb +53 -45
  98. data/bin/commands/reminders.rb +54 -41
  99. data/bin/commands/rtm.rb +16 -22
  100. data/bin/commands/search.rb +44 -33
  101. data/bin/commands/stars.rb +39 -29
  102. data/bin/commands/team.rb +50 -34
  103. data/bin/commands/team_billing.rb +19 -0
  104. data/bin/commands/team_externalTeams.rb +35 -0
  105. data/bin/commands/team_preferences.rb +19 -0
  106. data/bin/commands/team_profile.rb +15 -8
  107. data/bin/commands/tooling_tokens.rb +20 -0
  108. data/bin/commands/usergroups.rb +69 -53
  109. data/bin/commands/usergroups_users.rb +30 -19
  110. data/bin/commands/users.rb +114 -84
  111. data/bin/commands/users_admin.rb +29 -22
  112. data/bin/commands/users_discoverableContacts.rb +20 -0
  113. data/bin/commands/users_prefs.rb +14 -7
  114. data/bin/commands/users_profile.rb +27 -20
  115. data/bin/commands/views.rb +56 -0
  116. data/bin/commands/workflows.rb +44 -0
  117. data/bin/commands/workflows_triggers_permissions.rb +60 -0
  118. data/bin/slack +50 -46
  119. data/examples/files_upload_v2/.env.example +1 -0
  120. data/examples/{hi_real_time → files_upload_v2}/Gemfile +2 -2
  121. data/examples/files_upload_v2/README.md +13 -0
  122. data/examples/files_upload_v2/files_upload_v2.rb +45 -0
  123. data/examples/hi_real_time_and_web/Gemfile +1 -0
  124. data/examples/hi_real_time_and_web/hi.rb +7 -3
  125. data/examples/{hi_real_time_async_eventmachine → hi_real_time_async_async}/Gemfile +2 -1
  126. data/examples/{hi_real_time_async_eventmachine → hi_real_time_async_async}/hi.rb +12 -7
  127. data/examples/hi_web/Gemfile +1 -0
  128. data/examples/hi_web/hi.rb +1 -0
  129. data/examples/new_ticket/Gemfile +1 -0
  130. data/examples/new_ticket/new_ticket.rb +1 -0
  131. data/examples/oauth_v2/.env.example +4 -0
  132. data/examples/oauth_v2/Gemfile +7 -0
  133. data/examples/oauth_v2/README.md +33 -0
  134. data/examples/oauth_v2/oauth_v2.rb +60 -0
  135. data/lib/slack/config.rb +2 -2
  136. data/lib/slack/events/config.rb +32 -0
  137. data/lib/slack/events/request.rb +76 -0
  138. data/lib/slack/logger.rb +6 -5
  139. data/lib/slack/messages/formatting.rb +66 -1
  140. data/lib/slack/messages/message.rb +1 -4
  141. data/lib/slack/real_time/api/message.rb +6 -3
  142. data/lib/slack/real_time/api/message_id.rb +1 -0
  143. data/lib/slack/real_time/api/ping.rb +5 -2
  144. data/lib/slack/real_time/api/templates/event_handler.erb +5 -1
  145. data/lib/slack/real_time/api/typing.rb +5 -2
  146. data/lib/slack/real_time/client.rb +117 -54
  147. data/lib/slack/real_time/concurrency/async.rb +142 -0
  148. data/lib/slack/real_time/concurrency.rb +2 -2
  149. data/lib/slack/real_time/config.rb +12 -13
  150. data/lib/slack/real_time/models/base.rb +1 -4
  151. data/lib/slack/real_time/models/bot.rb +1 -0
  152. data/lib/slack/real_time/models/channel.rb +5 -0
  153. data/lib/slack/real_time/models/im.rb +1 -0
  154. data/lib/slack/real_time/models/{group.rb → mpim.rb} +2 -1
  155. data/lib/slack/real_time/models/team.rb +1 -0
  156. data/lib/slack/real_time/models/user.rb +1 -0
  157. data/lib/slack/real_time/models.rb +3 -1
  158. data/lib/slack/real_time/socket.rb +49 -17
  159. data/lib/slack/real_time/stores/base.rb +28 -14
  160. data/lib/slack/real_time/stores/starter.rb +325 -287
  161. data/lib/slack/real_time/stores/store.rb +271 -186
  162. data/lib/slack/real_time/stores.rb +2 -7
  163. data/lib/slack/utils/security.rb +44 -0
  164. data/lib/slack/version.rb +2 -1
  165. data/lib/slack/web/api/endpoints/admin_analytics.rb +28 -0
  166. data/lib/slack/web/api/endpoints/admin_apps.rb +78 -0
  167. data/lib/slack/web/api/endpoints/admin_apps_activities.rb +53 -0
  168. data/lib/slack/web/api/endpoints/admin_apps_approved.rb +37 -0
  169. data/lib/slack/web/api/endpoints/admin_apps_config.rb +40 -0
  170. data/lib/slack/web/api/endpoints/admin_apps_requests.rb +53 -0
  171. data/lib/slack/web/api/endpoints/admin_apps_restricted.rb +37 -0
  172. data/lib/slack/web/api/endpoints/admin_audit_anomaly_allow.rb +34 -0
  173. data/lib/slack/web/api/endpoints/admin_auth_policy.rb +72 -0
  174. data/lib/slack/web/api/endpoints/admin_barriers.rb +82 -0
  175. data/lib/slack/web/api/endpoints/admin_conversations.rb +397 -0
  176. data/lib/slack/web/api/endpoints/admin_conversations_ekm.rb +35 -0
  177. data/lib/slack/web/api/endpoints/admin_conversations_restrictAccess.rb +61 -0
  178. data/lib/slack/web/api/endpoints/admin_emoji.rb +88 -0
  179. data/lib/slack/web/api/endpoints/admin_functions.rb +36 -0
  180. data/lib/slack/web/api/endpoints/admin_functions_permissions.rb +41 -0
  181. data/lib/slack/web/api/endpoints/admin_inviteRequests.rb +61 -0
  182. data/lib/slack/web/api/endpoints/admin_inviteRequests_approved.rb +33 -0
  183. data/lib/slack/web/api/endpoints/admin_inviteRequests_denied.rb +33 -0
  184. data/lib/slack/web/api/endpoints/admin_roles.rb +73 -0
  185. data/lib/slack/web/api/endpoints/admin_teams.rb +50 -0
  186. data/lib/slack/web/api/endpoints/admin_teams_admins.rb +34 -0
  187. data/lib/slack/web/api/endpoints/admin_teams_owners.rb +34 -0
  188. data/lib/slack/web/api/endpoints/admin_teams_settings.rb +99 -0
  189. data/lib/slack/web/api/endpoints/admin_usergroups.rb +77 -0
  190. data/lib/slack/web/api/endpoints/admin_users.rb +167 -0
  191. data/lib/slack/web/api/endpoints/admin_users_session.rb +121 -0
  192. data/lib/slack/web/api/endpoints/admin_users_unsupportedVersions.rb +25 -0
  193. data/lib/slack/web/api/endpoints/admin_workflows.rb +67 -0
  194. data/lib/slack/web/api/endpoints/admin_workflows_collaborators.rb +42 -0
  195. data/lib/slack/web/api/endpoints/admin_workflows_permissions.rb +26 -0
  196. data/lib/slack/web/api/endpoints/admin_workflows_triggers_types_permissions.rb +41 -0
  197. data/lib/slack/web/api/endpoints/api.rb +2 -3
  198. data/lib/slack/web/api/endpoints/apps.rb +27 -0
  199. data/lib/slack/web/api/endpoints/apps_activities.rb +54 -0
  200. data/lib/slack/web/api/endpoints/apps_auth_external.rb +41 -0
  201. data/lib/slack/web/api/endpoints/apps_connections.rb +21 -0
  202. data/lib/slack/web/api/endpoints/apps_datastore.rb +181 -0
  203. data/lib/slack/web/api/endpoints/apps_event_authorizations.rb +34 -0
  204. data/lib/slack/web/api/endpoints/apps_manifest.rb +79 -0
  205. data/lib/slack/web/api/endpoints/assistant_search.rb +44 -0
  206. data/lib/slack/web/api/endpoints/assistant_threads.rb +68 -0
  207. data/lib/slack/web/api/endpoints/auth.rb +2 -1
  208. data/lib/slack/web/api/endpoints/auth_teams.rb +33 -0
  209. data/lib/slack/web/api/endpoints/bookmarks.rb +90 -0
  210. data/lib/slack/web/api/endpoints/bots.rb +4 -1
  211. data/lib/slack/web/api/endpoints/calls.rb +83 -0
  212. data/lib/slack/web/api/endpoints/calls_participants.rb +42 -0
  213. data/lib/slack/web/api/endpoints/canvases.rb +54 -0
  214. data/lib/slack/web/api/endpoints/canvases_access.rb +47 -0
  215. data/lib/slack/web/api/endpoints/canvases_sections.rb +27 -0
  216. data/lib/slack/web/api/endpoints/chat.rb +172 -87
  217. data/lib/slack/web/api/endpoints/chat_scheduledMessages.rb +40 -0
  218. data/lib/slack/web/api/endpoints/conversations.rb +190 -64
  219. data/lib/slack/web/api/endpoints/conversations_canvases.rb +28 -0
  220. data/lib/slack/web/api/endpoints/conversations_externalInvitePermissions.rb +31 -0
  221. data/lib/slack/web/api/endpoints/conversations_requestSharedInvite.rb +73 -0
  222. data/lib/slack/web/api/endpoints/dialog.rb +6 -10
  223. data/lib/slack/web/api/endpoints/dnd.rb +11 -5
  224. data/lib/slack/web/api/endpoints/emoji.rb +3 -0
  225. data/lib/slack/web/api/endpoints/files.rb +85 -36
  226. data/lib/slack/web/api/endpoints/files_comments.rb +4 -36
  227. data/lib/slack/web/api/endpoints/files_remote.rb +127 -0
  228. data/lib/slack/web/api/endpoints/functions.rb +43 -0
  229. data/lib/slack/web/api/endpoints/functions_distributions_permissions.rb +84 -0
  230. data/lib/slack/web/api/endpoints/functions_workflows_steps.rb +30 -0
  231. data/lib/slack/web/api/endpoints/functions_workflows_steps_responses.rb +30 -0
  232. data/lib/slack/web/api/endpoints/migration.rb +6 -3
  233. data/lib/slack/web/api/endpoints/oauth.rb +10 -32
  234. data/lib/slack/web/api/endpoints/oauth_v2.rb +48 -0
  235. data/lib/slack/web/api/endpoints/openid_connect.rb +42 -0
  236. data/lib/slack/web/api/endpoints/pins.rb +11 -18
  237. data/lib/slack/web/api/endpoints/reactions.rb +31 -20
  238. data/lib/slack/web/api/endpoints/reminders.rb +25 -12
  239. data/lib/slack/web/api/endpoints/rtm.rb +4 -22
  240. data/lib/slack/web/api/endpoints/search.rb +33 -18
  241. data/lib/slack/web/api/endpoints/stars.rb +23 -10
  242. data/lib/slack/web/api/endpoints/team.rb +38 -7
  243. data/lib/slack/web/api/endpoints/team_billing.rb +21 -0
  244. data/lib/slack/web/api/endpoints/team_externalTeams.rb +53 -0
  245. data/lib/slack/web/api/endpoints/team_preferences.rb +21 -0
  246. data/lib/slack/web/api/endpoints/team_profile.rb +2 -1
  247. data/lib/slack/web/api/endpoints/tooling_tokens.rb +24 -0
  248. data/lib/slack/web/api/endpoints/usergroups.rb +44 -25
  249. data/lib/slack/web/api/endpoints/usergroups_users.rb +23 -14
  250. data/lib/slack/web/api/endpoints/users.rb +57 -18
  251. data/lib/slack/web/api/endpoints/users_admin.rb +5 -2
  252. data/lib/slack/web/api/endpoints/users_discoverableContacts.rb +24 -0
  253. data/lib/slack/web/api/endpoints/users_prefs.rb +2 -0
  254. data/lib/slack/web/api/endpoints/users_profile.rb +11 -9
  255. data/lib/slack/web/api/endpoints/views.rb +86 -0
  256. data/lib/slack/web/api/endpoints/workflows.rb +63 -0
  257. data/lib/slack/web/api/endpoints/workflows_triggers_permissions.rb +87 -0
  258. data/lib/slack/web/api/endpoints.rb +136 -12
  259. data/lib/slack/web/api/error.rb +1 -0
  260. data/lib/slack/web/api/errors/server_error.rb +37 -0
  261. data/lib/slack/web/api/errors/slack_error.rb +14 -1
  262. data/lib/slack/web/api/errors/too_many_requests_error.rb +2 -4
  263. data/lib/slack/web/api/errors.rb +1396 -0
  264. data/lib/slack/web/api/helpers/files.rb +97 -0
  265. data/lib/slack/web/api/helpers.rb +13 -0
  266. data/lib/slack/web/api/mixins/conversations.id.rb +47 -0
  267. data/lib/slack/web/api/mixins/ids.id.rb +4 -3
  268. data/lib/slack/web/api/mixins/users.id.rb +18 -4
  269. data/lib/slack/web/api/mixins/users.search.rb +3 -1
  270. data/lib/slack/web/api/mixins.rb +2 -2
  271. data/lib/slack/web/api/options.rb +26 -0
  272. data/lib/slack/web/api/patches/.gitkeep +0 -0
  273. data/lib/slack/web/api/templates/command.erb +19 -12
  274. data/lib/slack/web/api/templates/endpoints.erb +2 -2
  275. data/lib/slack/web/api/templates/errors.erb +20 -0
  276. data/lib/slack/web/api/templates/method.erb +23 -3
  277. data/lib/slack/web/api/templates/method_spec.erb +40 -3
  278. data/lib/slack/web/client.rb +4 -1
  279. data/lib/slack/web/config.rb +9 -2
  280. data/lib/slack/web/faraday/connection.rb +11 -20
  281. data/lib/slack/web/faraday/options.rb +24 -0
  282. data/lib/slack/web/faraday/request.rb +6 -1
  283. data/lib/slack/web/faraday/response/raise_error.rb +14 -8
  284. data/lib/slack/web/faraday/response/wrap_error.rb +24 -0
  285. data/lib/slack/web/pagination/cursor.rb +7 -7
  286. data/lib/slack-ruby-client.rb +18 -6
  287. data/lib/slack.rb +1 -0
  288. data/lib/slack_ruby_client.rb +1 -0
  289. data/lib/tasks/git.rake +1 -0
  290. data/lib/tasks/real_time.rake +51 -21
  291. data/lib/tasks/update.rake +1 -0
  292. data/lib/tasks/web.rake +43 -17
  293. data/slack-ruby-client.gemspec +10 -14
  294. metadata +191 -307
  295. data/.travis.yml +0 -30
  296. data/bin/commands/apps_permissions.rb +0 -22
  297. data/bin/commands/channels.rb +0 -175
  298. data/bin/commands/groups.rb +0 -172
  299. data/bin/commands/im.rb +0 -67
  300. data/bin/commands/mpim.rb +0 -63
  301. data/bin/commands.rb +0 -33
  302. data/examples/hi_real_time/hi.gif +0 -0
  303. data/examples/hi_real_time/hi.rb +0 -37
  304. data/examples/hi_real_time_async_celluloid/Gemfile +0 -6
  305. data/examples/hi_real_time_async_celluloid/hi.rb +0 -36
  306. data/examples/hi_real_time_async_eventmachine/Procfile +0 -2
  307. data/lib/slack/real_time/concurrency/celluloid.rb +0 -117
  308. data/lib/slack/real_time/concurrency/eventmachine.rb +0 -60
  309. data/lib/slack/web/api/endpoints/apps_permissions.rb +0 -35
  310. data/lib/slack/web/api/endpoints/channels.rb +0 -265
  311. data/lib/slack/web/api/endpoints/groups.rb +0 -255
  312. data/lib/slack/web/api/endpoints/im.rb +0 -113
  313. data/lib/slack/web/api/endpoints/mpim.rb +0 -98
  314. data/lib/slack/web/api/endpoints/presence.rb +0 -23
  315. data/lib/slack/web/api/mixins/channels.id.json +0 -20
  316. data/lib/slack/web/api/mixins/channels.id.rb +0 -26
  317. data/lib/slack/web/api/mixins/groups.id.json +0 -20
  318. data/lib/slack/web/api/mixins/groups.id.rb +0 -26
  319. data/lib/slack/web/api/patches/chat.1.text-attachments-required.patch +0 -13
  320. data/lib/slack/web/api/patches/chat.2.attachments-json.patch +0 -17
  321. data/lib/slack/web/api/patches/chat.3.update-attachments-support.patch +0 -21
  322. data/lib/slack/web/api/patches/chat.4.postEphemeral-attachments-support.patch +0 -17
  323. data/lib/slack/web/api/patches/dialog.1.open-json-support.patch +0 -17
  324. data/lib/slack/web/api/templates/commands.erb +0 -5
  325. data/screenshots/register-bot.png +0 -0
  326. data/spec/fixtures/slack/web/429_error.yml +0 -85
  327. data/spec/fixtures/slack/web/auth_test_error.yml +0 -48
  328. data/spec/fixtures/slack/web/auth_test_success.yml +0 -57
  329. data/spec/fixtures/slack/web/channels_info.yml +0 -46
  330. data/spec/fixtures/slack/web/groups_info.yml +0 -43
  331. data/spec/fixtures/slack/web/paginated_users_list.yml +0 -181
  332. data/spec/fixtures/slack/web/rtm_connect.yml +0 -70
  333. data/spec/fixtures/slack/web/rtm_start.yml +0 -104
  334. data/spec/fixtures/slack/web/users_info.yml +0 -130
  335. data/spec/fixtures/slack/web/users_list.yml +0 -72
  336. data/spec/integration/integration_spec.rb +0 -139
  337. data/spec/slack/config_spec.rb +0 -14
  338. data/spec/slack/messages/formatting_spec.rb +0 -43
  339. data/spec/slack/real_time/api/message_spec.rb +0 -15
  340. data/spec/slack/real_time/api/ping_spec.rb +0 -15
  341. data/spec/slack/real_time/api/typing_spec.rb +0 -15
  342. data/spec/slack/real_time/client_spec.rb +0 -425
  343. data/spec/slack/real_time/concurrency/celluloid_spec.rb +0 -62
  344. data/spec/slack/real_time/concurrency/eventmachine_spec.rb +0 -47
  345. data/spec/slack/real_time/concurrency/it_behaves_like_a_realtime_socket.rb +0 -19
  346. data/spec/slack/real_time/event_handlers/bot_spec.rb +0 -44
  347. data/spec/slack/real_time/event_handlers/channel_spec.rb +0 -116
  348. data/spec/slack/real_time/event_handlers/event_handlers_spec.rb +0 -15
  349. data/spec/slack/real_time/event_handlers/group_spec.rb +0 -90
  350. data/spec/slack/real_time/event_handlers/im_spec.rb +0 -47
  351. data/spec/slack/real_time/event_handlers/team_spec.rb +0 -62
  352. data/spec/slack/real_time/event_handlers/user_spec.rb +0 -63
  353. data/spec/slack/real_time/rtm_connect_spec.rb +0 -13
  354. data/spec/slack/real_time/rtm_start_spec.rb +0 -13
  355. data/spec/slack/real_time/store_spec.rb +0 -11
  356. data/spec/slack/slack_spec.rb +0 -58
  357. data/spec/slack/version_spec.rb +0 -7
  358. data/spec/slack/web/api/endpoints/api_spec.rb +0 -7
  359. data/spec/slack/web/api/endpoints/apps_permissions_spec.rb +0 -15
  360. data/spec/slack/web/api/endpoints/bots_spec.rb +0 -7
  361. data/spec/slack/web/api/endpoints/conversations_spec.rb +0 -100
  362. data/spec/slack/web/api/endpoints/custom_specs/auth_spec.rb +0 -25
  363. data/spec/slack/web/api/endpoints/custom_specs/channels_spec.rb +0 -11
  364. data/spec/slack/web/api/endpoints/custom_specs/chat_spec.rb +0 -105
  365. data/spec/slack/web/api/endpoints/custom_specs/dialog_spec.rb +0 -28
  366. data/spec/slack/web/api/endpoints/custom_specs/groups_spec.rb +0 -11
  367. data/spec/slack/web/api/endpoints/custom_specs/users_spec.rb +0 -33
  368. data/spec/slack/web/api/endpoints/dnd_spec.rb +0 -12
  369. data/spec/slack/web/api/endpoints/emoji_spec.rb +0 -7
  370. data/spec/slack/web/api/endpoints/files_comments_spec.rb +0 -34
  371. data/spec/slack/web/api/endpoints/files_spec.rb +0 -43
  372. data/spec/slack/web/api/endpoints/im_spec.rb +0 -38
  373. data/spec/slack/web/api/endpoints/migration_spec.rb +0 -12
  374. data/spec/slack/web/api/endpoints/mpim_spec.rb +0 -38
  375. data/spec/slack/web/api/endpoints/oauth_spec.rb +0 -29
  376. data/spec/slack/web/api/endpoints/pins_spec.rb +0 -22
  377. data/spec/slack/web/api/endpoints/reactions_spec.rb +0 -17
  378. data/spec/slack/web/api/endpoints/reminders_spec.rb +0 -30
  379. data/spec/slack/web/api/endpoints/rtm_spec.rb +0 -7
  380. data/spec/slack/web/api/endpoints/search_spec.rb +0 -22
  381. data/spec/slack/web/api/endpoints/stars_spec.rb +0 -7
  382. data/spec/slack/web/api/endpoints/team_profile_spec.rb +0 -7
  383. data/spec/slack/web/api/endpoints/team_spec.rb +0 -7
  384. data/spec/slack/web/api/endpoints/usergroups_spec.rb +0 -27
  385. data/spec/slack/web/api/endpoints/usergroups_users_spec.rb +0 -20
  386. data/spec/slack/web/api/endpoints/users_admin_spec.rb +0 -17
  387. data/spec/slack/web/api/endpoints/users_prefs_spec.rb +0 -7
  388. data/spec/slack/web/api/endpoints/users_profile_spec.rb +0 -7
  389. data/spec/slack/web/api/error_spec.rb +0 -14
  390. data/spec/slack/web/api/errors/slack_error_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
  393. data/spec/slack/web/api/mixins/users_spec.rb +0 -39
  394. data/spec/slack/web/api/pagination/cursor_spec.rb +0 -70
  395. data/spec/slack/web/client_spec.rb +0 -174
  396. data/spec/spec_helper.rb +0 -14
  397. data/spec/support/queue_with_timeout.rb +0 -34
  398. data/spec/support/real_time/concurrency/mock.rb +0 -30
  399. data/spec/support/real_time/connected_client.rb +0 -21
  400. data/spec/support/real_time/event.rb +0 -11
  401. data/spec/support/token.rb +0 -10
  402. data/spec/support/vcr.rb +0 -9
  403. /data/examples/{hi_real_time_async_celluloid → hi_real_time_async_async}/Procfile +0 -0
data/README.md CHANGED
@@ -2,23 +2,86 @@ Slack Ruby Client
2
2
  =================
3
3
 
4
4
  [![Gem Version](https://badge.fury.io/rb/slack-ruby-client.svg)](http://badge.fury.io/rb/slack-ruby-client)
5
- [![Build Status](https://travis-ci.org/slack-ruby/slack-ruby-client.svg?branch=master)](https://travis-ci.org/slack-ruby/slack-ruby-client)
6
- [![Code Climate](https://codeclimate.com/github/slack-ruby/slack-ruby-client/badges/gpa.svg)](https://codeclimate.com/github/slack-ruby/slack-ruby-client)
5
+ [![Integration Tests](https://github.com/slack-ruby/slack-ruby-client/actions/workflows/integration_test.yml/badge.svg?branch=master)](https://github.com/slack-ruby/slack-ruby-client/actions/workflows/integration_test.yml)
6
+ [![Tests](https://github.com/slack-ruby/slack-ruby-client/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/slack-ruby/slack-ruby-client/actions/workflows/test.yml)
7
+ [![Coverage Status](https://coveralls.io/repos/github/slack-ruby/slack-ruby-client/badge.svg?branch=master)](https://coveralls.io/github/slack-ruby/slack-ruby-client?branch=master)
7
8
 
8
- A Ruby client for the Slack [Web](https://api.slack.com/web) and [RealTime Messaging](https://api.slack.com/rtm) APIs. Comes with a handy command-line client, too. If you are not familiar with these concepts, you might want to watch [this video](http://code.dblock.org/2016/03/11/your-first-slack-bot-service-video.html).
9
+ A Ruby client for the Slack [Web](https://api.slack.com/web), [RealTime Messaging](https://api.slack.com/rtm) and [Events](https://api.slack.com/events-api) APIs. Comes with a handy command-line client, too. If you are not familiar with these concepts, you might want to watch [this video](http://code.dblock.org/2016/03/11/your-first-slack-bot-service-video.html).
9
10
 
10
11
  ![](slack.png)
11
12
 
13
+ # Table of Contents
14
+
15
+ - [Useful to Me?](#useful-to-me)
16
+ - [Stable Release](#stable-release)
17
+ - [Installation](#installation)
18
+ - [Usage](#usage)
19
+ - [Create a New Bot Integration](#create-a-new-bot-integration)
20
+ - [OAuth Code Grant](#oauth-code-grant)
21
+ - [Using an API Token](#using-an-api-token)
22
+ - [Global Settings](#global-settings)
23
+ - [Web Client](#web-client)
24
+ - [Web Client Examples](#web-client-examples)
25
+ - [Test Auth](#test-auth)
26
+ - [Send Messages](#send-messages)
27
+ - [List Channels](#list-channels)
28
+ - [Upload a File](#upload-a-file)
29
+ - [Get Channel Info](#get-channel-info)
30
+ - [Get User Info](#get-user-info)
31
+ - [Search for a User](#search-for-a-user)
32
+ - [Other](#other)
33
+ - [JSON Arguments](#json-arguments)
34
+ - [Web Client Options](#web-client-options)
35
+ - [Pagination Support](#pagination-support)
36
+ - [Character Encoding](#character-encoding)
37
+ - [Error Handling](#error-handling)
38
+ - [Slack Errors](#slack-errors)
39
+ - [Rate Limiting](#rate-limiting)
40
+ - [Other Errors](#other-errors)
41
+ - [RealTime Client](#realtime-client)
42
+ - [Configuring Slack::RealTime::Client](#configuring-slackrealtimeclient)
43
+ - [Caveats](#caveats)
44
+ - [websocket_ping](#websocket_ping)
45
+ - [RealTime Store](#realtime-store)
46
+ - [Slack::RealTime::Stores::Starter](#slackrealtimestoresstarter)
47
+ - [Slack::RealTime::Stores::Store](#slackrealtimestoresstore)
48
+ - [Combining RealTime and Web Clients](#combining-realtime-and-web-clients)
49
+ - [Concurrency](#concurrency)
50
+ - [Async](#async)
51
+ - [Events API](#events-api)
52
+ - [Configuring Slack::Events](#configuring-slackevents)
53
+ - [Verifying the Request Signature](#verifying-the-request-signature)
54
+ - [Message Handling](#message-handling)
55
+ - [Formatting Messages](#formatting-messages)
56
+ - [Date and Time Formatting](#date-and-time-formatting)
57
+ - [Channel ID Formatting](#channel-id-formatting)
58
+ - [User ID Formatting](#user-id-formatting)
59
+ - [Group ID Formatting](#group-id-formatting)
60
+ - [URL Formatting](#url-formatting)
61
+ - [Markdown Formatting](#markdown-formatting)
62
+ - [Parsing Messages](#parsing-messages)
63
+ - [Unescaping Message Content](#unescaping-message-content)
64
+ - [Escaping Message Content](#escaping-message-content)
65
+ - [Command-Line Client](#command-line-client)
66
+ - [Authenticate with Slack](#authenticate-with-slack)
67
+ - [Send a Message](#send-a-message)
68
+ - [Get Channel Info](#get-channel-info-1)
69
+ - [List Users](#list-users)
70
+ - [Enterprise Support](#enterprise-support)
71
+ - [History](#history)
72
+ - [Security](#security)
73
+ - [Contributing](#contributing)
74
+ - [Copyright and License](#copyright-and-license)
75
+
12
76
  ## Useful to Me?
13
77
 
14
- * This piece of the puzzle will help you send messages to Slack via the Web API and send and receive messages via the Real Time API.
15
- * If you're trying to respond to slash commands, just write a basic web application and use this library to call the Slack Web API.
16
- * If you're trying to build a Real Time bot, use [slack-ruby-bot](https://github.com/dblock/slack-ruby-bot), which uses this library.
17
- * If you're trying to roll out a full service with Slack button integration to multiple teams, check out [slack-ruby-bot-server](https://github.com/dblock/slack-ruby-bot-server), which is built on top of slack-ruby-bot, which uses this library.
78
+ * This library lets you send messages to Slack via the Web API, send and receive messages via the Real Time Messaging API, and facilitates integration with the Events API.
79
+ * To write a complete bot for Slack you need more than this library, and it's much easier to start with [slack-ruby-bot-server-events](https://github.com/slack-ruby/slack-ruby-bot-server-events).
80
+ * To respond to slash commands, interactive components, or events at the lowest level, implement a web application using your favorite web framework, and use this library to call the Slack Web API, and to verify that events are coming from Slack.
18
81
 
19
82
  ## Stable Release
20
83
 
21
- You're reading the documentation for the **stable** release of slack-ruby-client, 0.11.0. See [UPGRADING](UPGRADING.md) when upgrading from an older version.
84
+ You're reading the documentation for the **stable** release of slack-ruby-client 2.7.0. See [UPGRADING](UPGRADING.md) when upgrading from an older version.
22
85
 
23
86
  ## Installation
24
87
 
@@ -28,11 +91,10 @@ Add to Gemfile.
28
91
  gem 'slack-ruby-client'
29
92
  ```
30
93
 
31
- If you're going to be using the RealTime client, add either `eventmachine` and `faye-websocket` or `celluloid-io`. See below for more information about concurrency.
94
+ If you're going to be using the RealTime client, add `async-websocket`. See below for more information about concurrency.
32
95
 
33
96
  ```
34
- gem 'eventmachine'
35
- gem 'faye-websocket'
97
+ gem 'async-websocket', '~> 0.8.0'
36
98
  ```
37
99
 
38
100
  Run `bundle install`.
@@ -41,11 +103,15 @@ Run `bundle install`.
41
103
 
42
104
  ### Create a New Bot Integration
43
105
 
44
- This is something done in Slack, under [integrations](https://my.slack.com/services). Create a [new bot](https://my.slack.com/services/new/bot), and note its API token.
106
+ To integrate your bot with Slack, you must first create a new [Slack App](https://api.slack.com/apps).
107
+
108
+ ### OAuth Code Grant
109
+
110
+ Once created, go to the app's Basic Info tab and grab the Client ID and Client Secret. You'll need these in order complete an [OAuth Workflow](https://api.slack.com/authentication/oauth-v2). A working sample that starts a local web server and obtains a bot or a user token for your app using OAuth v2 is available in [examples/oauth_v2](examples/oauth_v2).
45
111
 
46
- ![](screenshots/register-bot.png)
112
+ ### Using an API Token
47
113
 
48
- ### Use the API Token
114
+ Although OAuth is recommended, you can also [generate an API token](https://api.slack.com/tutorials/tracks/getting-a-token) for your app and use it for some interactions.
49
115
 
50
116
  ```ruby
51
117
  Slack.configure do |config|
@@ -68,14 +134,18 @@ logger | An optional logger, defaults to `::Logger.new(STDOUT)` at `Logger
68
134
 
69
135
  The Slack Web API allows you to build applications that interact with Slack.
70
136
 
71
- #### Test Auth
137
+ #### Web Client Examples
138
+
139
+ Here are some examples of how to use the web client with the Web API.
140
+
141
+ ##### Test Auth
72
142
 
73
143
  ```ruby
74
144
  client = Slack::Web::Client.new
75
145
  client.auth_test
76
146
  ```
77
147
 
78
- #### Send Messages
148
+ ##### Send Messages
79
149
 
80
150
  Send messages with [chat_PostMessage](https://api.slack.com/methods/chat.postMessage).
81
151
 
@@ -87,44 +157,80 @@ See a fully working example in [examples/hi_web](examples/hi_web/hi.rb).
87
157
 
88
158
  ![](examples/hi_web/hi.gif)
89
159
 
90
- #### List Channels
160
+ ##### List Channels
91
161
 
92
- List channels with [channels_list](https://api.slack.com/methods/channels.list).
162
+ List channels with [conversations_list](https://api.slack.com/methods/conversations.list).
93
163
 
94
164
  ```ruby
95
- channels = client.channels_list.channels
165
+ channels = client.conversations_list.channels
96
166
 
97
167
  general_channel = channels.detect { |c| c.name == 'general' }
98
168
  ```
99
169
 
100
- #### Upload a File
170
+ ##### Upload a File
101
171
 
102
- Upload a file with [files_upload](https://api.slack.com/methods/files.upload).
172
+ Upload files with [sequenced API calls](https://api.slack.com/messaging/files#uploading_files).
173
+
174
+ This library provides a helper method `files_upload_v2` that wraps the three separate API calls.
175
+
176
+ Upload a single file.
177
+
178
+ ```ruby
179
+ client.files_upload_v2(
180
+ # required options
181
+ filename: 'results.pdf', # this is used for the file title, unless a :title option is provided
182
+ content: File.read('/users/me/results.pdf'), # the string contents of the file
183
+
184
+ # optional options
185
+ channels: ['C000000', 'C000001'], # channel IDs to share the file in (:channel_id, :channel, or :channels are all supported)
186
+ initial_comment: 'Sharing the Q1 results :tada:', # the message that is included with the file share thread
187
+ snippet_type: 'text', # the type of snippet
188
+ title: 'Q1 Results', # sets the title of the file, overriding the filename
189
+ thread_ts: '1738331487.481469' # specifies a thread to add this file to
190
+ )
191
+ ```
192
+
193
+ Upload multiple files.
194
+
195
+ ```ruby
196
+ client.files_upload_v2(
197
+ files: [
198
+ { filename: 'report.pdf', content: File.read('/users/me/report.pdf'), title: 'Monthly Report' },
199
+ { filename: 'data.csv', content: File.read('/users/me/data.csv'), title: 'Raw Data' }
200
+ ],
201
+ channels: ['#general'],
202
+ initial_comment: 'Here are the monthly results!'
203
+ )
204
+ ```
205
+
206
+ You can use a channel ID passed as `channel_id`, a single channel as `channel`, an array of channel IDs as `channels`, or a channel name or names (prefixed with `#`) in `files_upload_v2`. Lookup by name is not supported by the Slack API and this method called invokes `conversations_list` in order to locate the channel ID. This invocation can have a cost if you have many Slack channels and is only recommended when you intend to list channels anyway.
207
+
208
+ Note: This library includes a `files_upload` method that uses a deprecated endpoint `files.upload` that will [no longer be supported on 3/11/2025](https://api.slack.com/methods/files.upload#markdown).
103
209
 
104
210
  ```ruby
105
211
  client.files_upload(
106
212
  channels: '#general',
107
213
  as_user: true,
108
- file: Faraday::UploadIO.new('/path/to/avatar.jpg', 'image/jpeg'),
214
+ file: Faraday::Multipart::FilePart.new('/path/to/avatar.jpg', 'image/jpeg'),
109
215
  title: 'My Avatar',
110
216
  filename: 'avatar.jpg',
111
217
  initial_comment: 'Attached a selfie.'
112
218
  )
113
219
  ```
114
220
 
115
- ### Get Channel Info
221
+ ##### Get Channel Info
116
222
 
117
- You can use a channel ID or name (prefixed with `#`) in all functions that take a `:channel` argument. Lookup by name is not supported by the Slack API and the `channels_id` method called invokes `channels_list` in order to locate the channel ID.
223
+ You can use a channel ID or name (prefixed with `#`) in all functions that take a `:channel` argument. Lookup by name is not supported by the Slack API and the `channels_id` method called invokes `conversations_list` in order to locate the channel ID. This invocation can have a cost if you have many Slack channels. In this scenario, we encourage you to use channel id.
118
224
 
119
225
  ```ruby
120
- client.channels_info(channel: 'C04KB5X4D') # calls channels_info
226
+ client.conversations_info(channel: 'C04KB5X4D') # calls conversations_info
121
227
  ```
122
228
 
123
229
  ```ruby
124
- client.channels_info(channel: '#general') # calls channels_list followed by channels_info
230
+ client.conversations_info(channel: '#general') # calls conversations_list followed by conversations_info
125
231
  ```
126
232
 
127
- ### Get User Info
233
+ ##### Get User Info
128
234
 
129
235
  You can use a user ID or name (prefixed with `@`) in all functions that take a `:user` argument. Lookup by name is not supported by the Slack API and the `users_id` method called invokes `users_list` in order to locate the user ID.
130
236
 
@@ -136,7 +242,7 @@ client.users_info(user: 'U092BDCLV') # calls users_info
136
242
  client.users_info(user: '@dblock') # calls users_list followed by users_info
137
243
  ```
138
244
 
139
- ### Search for a User
245
+ ##### Search for a User
140
246
 
141
247
  Constructs an in-memory index of users and searches it. If you want to use this functionality, add the [picky](https://github.com/floere/picky) gem to your project's Gemfile.
142
248
 
@@ -144,16 +250,41 @@ Constructs an in-memory index of users and searches it. If you want to use this
144
250
  client.users_search(user: 'dblock')
145
251
  ```
146
252
 
147
- #### Other
253
+ ##### Other
148
254
 
149
255
  Refer to the [Slack Web API Method Reference](https://api.slack.com/methods) for the list of all available functions.
150
256
 
257
+ #### JSON Arguments
258
+
259
+ The Web API expects certain arguments to be sent as JSON-encoded strings. With the client you can pass these args as ruby hashes or arrays and they will be converted automatically to JSON, or you can provide the JSON directly.
260
+
261
+ ```ruby
262
+ # As ruby objects
263
+ client.chat_postMessage(
264
+ channel: 'C123456',
265
+ text: 'Hello World',
266
+ blocks: [{type: 'section', text: {type: 'mrkdwn', text: 'Hello World'}}]
267
+ )
268
+
269
+ # As a JSON string
270
+ client.chat_postMessage(
271
+ channel: 'C123456',
272
+ text: 'Hello World',
273
+ blocks: JSON.dump([{type: 'section', text: {type: 'mrkdwn', text: 'Hello World'}}])
274
+ )
275
+ client.chat_postMessage(
276
+ channel: 'C123456',
277
+ text: 'Hello World',
278
+ blocks: '[{"type":"section","text":{"type":"mrkdwn","text":"Hello World"}}]'
279
+ )
280
+ ```
281
+
151
282
  #### Web Client Options
152
283
 
153
284
  You can configure the Web client either globally or via the initializer.
154
285
 
155
286
  ```ruby
156
- Slack::Web::Client.config do |config|
287
+ Slack::Web::Client.configure do |config|
157
288
  config.user_agent = 'Slack Ruby Client/1.0'
158
289
  end
159
290
  ```
@@ -164,26 +295,33 @@ client = Slack::Web::Client.new(user_agent: 'Slack Ruby Client/1.0')
164
295
 
165
296
  The following settings are supported.
166
297
 
167
- setting | description
168
- --------------------|-------------------------------------------------------------------------------------------------
169
- token | Slack API token.
170
- user_agent | User-agent, defaults to _Slack Ruby Client/version_.
171
- proxy | Optional HTTP proxy.
172
- ca_path | Optional SSL certificates path.
173
- ca_file | Optional SSL certificates file.
174
- endpoint | Slack endpoint, default is _https://slack.com/api_.
175
- logger | Optional `Logger` instance that logs HTTP requests.
176
- timeout | Optional open/read timeout in seconds.
177
- open_timeout | Optional connection open timeout in seconds.
178
- default_page_size | Optional page size for paginated requests, default is _100_.
179
- default_max_retries | Optional number of retries for paginated requests, default is _100_.
298
+ setting | description
299
+ -----------------------------|-------------------------------------------------------------------------------------------------
300
+ token | Slack API token.
301
+ user_agent | User-agent, defaults to _Slack Ruby Client/version_.
302
+ proxy | Optional HTTP proxy.
303
+ ca_path | Optional SSL certificates path.
304
+ ca_file | Optional SSL certificates file.
305
+ endpoint | Slack endpoint, default is _https://slack.com/api_.
306
+ logger | Optional `Logger` instance that logs HTTP requests.
307
+ timeout | Optional open/read timeout in seconds.
308
+ open_timeout | Optional connection open timeout in seconds.
309
+ default_page_size | Optional page size for paginated requests, default is _100_.
310
+ conversations_id_page_size | Optional page size for conversations_list requests made when calculating conversation id from a conversation name, default is _nil_, which will use the default_page_size.
311
+ users_id_page_size | Optional page size for users_list requests made when calculating user id from a user name, default is _nil_, which will use the default_page_size.
312
+ default_max_retries | Optional number of retries for paginated requests, default is _100_.
313
+ adapter | Optional HTTP adapter to use, defaults to `Faraday.default_adapter`.
180
314
 
181
315
  You can also pass request options, including `timeout` and `open_timeout` into individual calls.
182
316
 
183
317
  ```ruby
184
- client.channels_list(request: { timeout: 180 })
318
+ client.conversations_list(request: { timeout: 180 })
185
319
  ```
186
320
 
321
+ You can also control what proxy options are used by modifying the `http_proxy` environment variable per [Net::HTTP's documentation](https://docs.ruby-lang.org/en/2.0.0/Net/HTTP.html#class-Net::HTTP-label-Proxies).
322
+
323
+ Note that Docker on OSX seems to incorrectly set the proxy, causing `Faraday::ConnectionFailed, ERROR -- : Failed to open TCP connection to : (getaddrinfo: Name or service not known)`. You might need to manually unset `http_proxy` in that case, eg. `http_proxy="" bundle exec ruby ./my_bot.rb`.
324
+
187
325
  #### Pagination Support
188
326
 
189
327
  The Web client natively supports [cursor pagination](https://api.slack.com/docs/pagination#cursors) for methods that allow it, such as `users_list`. Supply a block and the client will make repeated requests adjusting the value of `cursor` with every response. The default limit is set to 100 and can be adjusted via `Slack::Web::Client.config.default_page_size` or by passing it directly into the API call.
@@ -210,6 +348,60 @@ end
210
348
  all_members # many thousands of team members retrieved 10 at a time
211
349
  ```
212
350
 
351
+ #### Character Encoding
352
+
353
+ Note that Slack expects `text` to be UTF-8 encoded. If your messages appear with text such as `BAD+11` in Slack, check `text.encoding` and `.encode(Encoding::UTF_8)` your messages before sending them to Slack.
354
+
355
+ ```ruby
356
+ text = 'characters such as "Ñ", "Á", "É"'
357
+ text.encoding
358
+ => #<Encoding:UTF-8>
359
+ client.chat_postMessage(channel: '#general', text: text, as_user: true)
360
+ # renders 'characters such as "Ñ", "Á", "É"' in Slack
361
+
362
+ text = text.encode(Encoding::ISO_8859_1)
363
+ text.encoding
364
+ # => #<Encoding:ISO-8859-1>
365
+ client.chat_postMessage(channel: '#general', text: text, as_user: true)
366
+ # renders 'characters such as "BAD+11", "", "BAD+9"' in Slack
367
+ ```
368
+
369
+ #### Error Handling
370
+
371
+ ##### Slack Errors
372
+
373
+ If Slack returns an error for the request, then an error will be raised. The error class is specific to the type of error that Slack returns. For instance if Slack returns `account_inactive` then the error will be `Slack::Web::Api::Errors::AccountInactive`. This allows you to handle certain types of errors as needed:
374
+
375
+ ```ruby
376
+ rescue Slack::Web::Api::Errors::AccountInactive => e
377
+ # deal with inactive account
378
+ end
379
+ ```
380
+
381
+ All of these errors inherit from `Slack::Web::Api::Errors::SlackError`, so you can handle or silence all errors if necessary:
382
+
383
+ ```ruby
384
+ rescue Slack::Web::Api::Errors::SlackError => e
385
+ # capture all Slack errors
386
+ end
387
+ ```
388
+
389
+ If there's a new error type that is not yet known by this library, then it will raise `Slack::Web::Api::Errors::SlackError`. (Update the Web API if you find that errors are missing — see [CONTRIBUTING](CONTRIBUTING.md).)
390
+
391
+ In all of these cases the error message contains the error code, which is also accessible with `slack_error.error`. In case of multiple errors, the error message contains the error codes separated by commas, or they are accessible as an array with `slack_error.errors`. The original response is also accessible using the `response` attribute. The `response_metadata` is accessible with `slack_error.response_metadata`.
392
+
393
+ ##### Rate Limiting
394
+
395
+ If you exceed [Slack’s rate limits](https://api.slack.com/docs/rate-limits), a `Slack::Web::Api::Errors::TooManyRequestsError` will be raised instead. (This does not inherit from `Slack::Web::Api::Errors::SlackError`.)
396
+
397
+ ##### Other Errors
398
+
399
+ When Slack is temporarily unavailable a subclass of `Slack::Web::Api::Errors::ServerError` will be raised and the original `Faraday::Error` will be accesible via `exception.cause`. (Starting with 0.18.0 this is no longer a subclass of `Slack::Web::Api::Errors::SlackError`.)
400
+
401
+ Specifically `Slack::Web::Api::Errors::ParsingError` will be raised on non-json response (i.e. 200 OK with `Slack unavailable` HTML page) and `Slack::Web::Api::Errors::HttpRequestError` subclasses for connection failures (`Slack::Web::Api::Errors::TimeoutError` for read/open timeouts & `Slack::Web::Api::Errors::UnavailableError` for 5xx HTTP responses).
402
+
403
+ In any other case, a `Faraday::ClientError` will be raised.
404
+
213
405
  ### RealTime Client
214
406
 
215
407
  The Real Time Messaging API is a WebSocket-based API that allows you to receive events from Slack in real time and send messages as user.
@@ -224,9 +416,9 @@ end
224
416
  client.on :message do |data|
225
417
  case data.text
226
418
  when 'bot hi' then
227
- client.message channel: data.channel, text: "Hi <@#{data.user}>!"
419
+ client.message(channel: data.channel, text: "Hi <@#{data.user}>!")
228
420
  when /^bot/ then
229
- client.message channel: data.channel, text: "Sorry <@#{data.user}>, what?"
421
+ client.message(channel: data.channel, text: "Sorry <@#{data.user}>, what?")
230
422
  end
231
423
  end
232
424
 
@@ -253,37 +445,12 @@ You can send a ping with `ping`.
253
445
  client.ping
254
446
  ```
255
447
 
256
- By default, the RealTime client exposes and maintains a local store with the properties of [rtm.start](https://api.slack.com/methods/rtm.start) upon a successful connection.
257
-
258
- property | description
259
- ---------|-------------------------------------------------------------------------------------------------
260
- url | A WebSocket Message Server URL.
261
- self | The authenticated bot user.
262
- team | Details on the authenticated user's team.
263
- users | A hash of user objects by user ID.
264
- channels | A hash of channel objects, one for every channel visible to the authenticated user.
265
- groups | A hash of group objects, one for every group the authenticated user is in.
266
- ims | A hash of IM objects, one for every direct message channel visible to the authenticated user.
267
- bots | Details of the integrations set up on this team.
268
-
269
- It also tracks changes, such as users being renamed, added or deleted, therefore `client.users` is always up-to-date.
270
-
271
- Tracking with a local store can be disabled with `Slack::RealTime::Client.new(store_class: nil)`. Other stores are also available.
272
-
273
- #### Slack::RealTime::Stores::Store
274
-
275
- The default store that tracks all changes. By default the client will be connected using `rtm_start`.
276
-
277
- #### Slack::RealTime::Stores::Starter
278
-
279
- A smaller store that only stores and tracks information about the bot user, but not channels, users, groups, ims or bots. By default the client will be connected using `rtm_connect`.
280
-
281
- ### Configuring Slack::RealTime::Client
448
+ #### Configuring Slack::RealTime::Client
282
449
 
283
450
  You can configure the RealTime client either globally or via the initializer.
284
451
 
285
452
  ```ruby
286
- Slack::RealTime::Client.config do |config|
453
+ Slack::RealTime::Client.configure do |config|
287
454
  config.websocket_ping = 42
288
455
  end
289
456
  ```
@@ -297,29 +464,81 @@ The following settings are supported.
297
464
  setting | description
298
465
  ----------------|-----------------------------------------------------------------------------------------------------
299
466
  token | Slack API token.
300
- websocket_ping | The number of seconds that indicates how often the WebSocket should send ping frames, default is 30.
467
+ websocket_ping | How long the socket can be idle before sending a ping message to confirm it's still connected, default is 30.
301
468
  websocket_proxy | Connect via proxy, include `:origin` and `:headers`.
302
- store_class | Local store class name, default is an in-memory `Slack::RealTime::Stores::Store`.
303
- start_method | Optional start method, either `:rtm_start` or `:rtm_connect`.
304
- start_options | Options to pass into `rtm.start` or `rtm.connect`, default is `{ request: { timeout: 180 } }`.
469
+ start_options | Options to pass to `rtm.connect`, default is `{ request: { timeout: 180 } }`.
470
+ store_class | Local store class, default is an in-memory `Slack::RealTime::Stores::Starter`.
471
+ store_options | Options to initialize the store, default is `{}`.
472
+ async_handlers | Option to run handlers asynchronously. Valid options are `:all` or `:none`, default is `:none`.
305
473
  logger | Optional `Logger` instance that logs RealTime requests and socket data.
306
474
 
307
- Note that the RealTime client uses a Web client to obtain the WebSocket URL via [rtm.start](https://api.slack.com/methods/rtm.start) or [rtm.connect](https://api.slack.com/methods/rtm.connect). While `token` and `logger` options are passed down from the RealTime client, you may also configure Web client options via `Slack::Web::Client.configure` as described above.
475
+ Note that the RealTime client uses a Web client to obtain the WebSocket URL via [rtm.connect](https://api.slack.com/methods/rtm.connect). While `token` and `logger` options are passed down from the RealTime client, you may also configure Web client options via `Slack::Web::Client.configure` as described above.
476
+
477
+ See a fully working example in [examples/hi_real_time_and_web](examples/hi_real_time_and_web/hi.rb).
478
+
479
+ ![](examples/hi_real_time_and_web/hi.gif)
480
+
481
+ ##### Caveats
482
+
483
+ ###### `websocket_ping`
484
+
485
+ This setting determines how long the socket can be idle before sending a ping message to confirm it's still connected.
486
+
487
+ It's important to note that if a ping message was sent and no response was received within the amount of time specified in `websocket_ping` the client will attempt to reestablish it's connection to the message server.
488
+
489
+ Note that the ping may take between `websocket_ping` and `websocket_ping * 3/2` seconds to actually trigger when there is no activity on the socket. This is because the timer that checks whether to ping is triggered at every `websocket_ping / 2` interval.
490
+
491
+ To disable this feature set `websocket_ping` to 0.
492
+
493
+ #### RealTime Store
308
494
 
309
- See a fully working example in [examples/hi_real_time](examples/hi_real_time/hi.rb).
495
+ The RealTime client exposes and maintains a local store upon successful connection.
496
+ Event hooks keep the store's cached data up-to-date.
310
497
 
311
- ![](examples/hi_real_time/hi.gif)
498
+ Tracking with a local store can be disabled with `Slack::RealTime::Client.new(store_class: nil)`.
312
499
 
313
- ### Connection Methods
500
+ ##### `Slack::RealTime::Stores::Starter`
314
501
 
315
- The RealTime client uses either [rtm.start](https://api.slack.com/methods/rtm.start) or [rtm.connect](https://api.slack.com/methods/rtm.connect) to open a connection. The former retrieves a lot of team information while the latter only serves connection purposes and is preferred. You should let the library choose the right method for you based on the `store_class` used and override this behavior with `start_method` when necessary.
502
+ A small store that only caches and tracks data returned in the [rtm.connect](https://api.slack.com/methods/rtm.connect#examples) response.
503
+ This store provides `self` and `team` for accessing the limited data about the authenticated user and its workspace, but does not cache other users or bots, channels, or direct messages.
316
504
 
505
+ ##### `Slack::RealTime::Stores::Store`
506
+
507
+ A more complete store that tracks most changes visible to the authenticated user.
508
+
509
+ You can see all of the cache types in the table below (each is a hash indexed by its objects' `id`).
510
+
511
+ Cache | Description
512
+ -------------------|-------------------------------------------------------------------------------------------------
513
+ `teams` | Workspaces (teams). Will likely contain only one `team`.
514
+ `users` | All [user](https://api.slack.com/types/user) objects, including `self`.
515
+ `bots` | All [bot users](https://api.slack.com/bot-users) (from Slack Apps and legacy custom integrations).
516
+ `public_channels` | Public [conversation](https://api.slack.com/types/conversation) objects.
517
+ `private_channels` | Private [conversation](https://api.slack.com/types/conversation) and [group](https://api.slack.com/types/group) objects with the authenticated user as a member.
518
+ `ims` | Visible [im](https://api.slack.com/types/im) objects, direct message channels with the authenticated user.
519
+ `mpims` | Visible [mpim](https://api.slack.com/types/mpim) objects, multiparty direct message channels that include the authenticated user.
520
+
521
+ By default, none of these caches are initialized with data beyond what is returned from [rtm.connect](https://api.slack.com/methods/rtm.connect#examples), same as [Slack::RealTime::Stores::Starter](#slackrealtimestoresstarter).
522
+ When configured, this store initializes its caches by making additional calls to Web API methods upon successful connection to the RTM API (i.e. "hello" message).
523
+
524
+ Configure by specifying which caches to fetch:
317
525
  ```ruby
318
- Slack::RealTime::Client.config do |config|
319
- config.start_method = :rtm_start
526
+ Slack::RealTime::Client.configure do |config|
527
+ config.store_class = Slack::RealTime::Stores::Store
528
+ config.store_options = { caches: %i[teams users public_channels private_channels ims] }
529
+ end
530
+ ```
531
+ or with the `:all` option:
532
+ ```ruby
533
+ Slack::RealTime::Client.configure do |config|
534
+ config.store_class = Slack::RealTime::Stores::Store
535
+ config.store_options = { caches: :all }
320
536
  end
321
537
  ```
322
538
 
539
+ Note: For `teams`, this makes a single call to `team.info`, while for `users` and all conversation-like types, this makes paginated calls to `users.list` and `conversations.list` respectively.
540
+ Only `bots` requires a separate call for every bot user, so may be slow if your workplace has a lot of bot users.
541
+
323
542
  ### Combining RealTime and Web Clients
324
543
 
325
544
  Since the Web client is used to obtain the RealTime client's WebSocket URL, you can continue using the Web client in combination with the RealTime client.
@@ -330,9 +549,9 @@ client = Slack::RealTime::Client.new
330
549
  client.on :message do |data|
331
550
  case data.text
332
551
  when 'bot hi' then
333
- client.web_client.chat_postMessage channel: data.channel, text: "Hi <@#{data.user}>!"
552
+ client.web_client.chat_postMessage(channel: data.channel, text: "Hi <@#{data.user}>!")
334
553
  when /^bot/ then
335
- client.web_client.chat_postMessage channel: data.channel, text: "Sorry <@#{data.user}>, what?"
554
+ client.web_client.chat_postMessage(channel: data.channel, text: "Sorry <@#{data.user}>, what?")
336
555
  end
337
556
  end
338
557
 
@@ -343,90 +562,207 @@ See a fully working example in [examples/hi_real_time_and_web](examples/hi_real_
343
562
 
344
563
  ![](examples/hi_real_time_and_web/hi.gif)
345
564
 
346
- ### Large Team Considerations
565
+ #### Concurrency
347
566
 
348
- The `rtm.start` call downloads a large amount of data. For large teams, consider reducing the amount of unnecessary data downloaded with `start_options`. You may also want to increase the default timeout of 180 seconds.
567
+ `Slack::RealTime::Client` needs help from a concurrency library and supports [Async](https://github.com/socketry/async).
349
568
 
350
569
  ```ruby
351
- Slack::RealTime::Client.config do |config|
352
- # Return timestamp only for latest message object of each channel.
353
- config.start_options[:simple_latest] = true
354
- # Skip unread counts for each channel.
355
- config.start_options[:no_unreads] = true
356
- # Increase request timeout to 6 minutes.
357
- config.start_options[:request][:timeout] = 360
570
+ Slack::RealTime.configure do |config|
571
+ config.concurrency = Slack::RealTime::Concurrency::Async
358
572
  end
359
573
  ```
360
574
 
361
- See [#134](https://github.com/slack-ruby/slack-ruby-client/issues/134) for a discussion on this topic.
575
+ Use `client.start_async` instead of `client.start!`. A good example of such application is [slack-ruby-bot-server](https://github.com/slack-ruby/slack-ruby-bot-server).
362
576
 
363
- #### Concurrency
577
+ ```ruby
578
+ client = Slack::RealTime::Client.new
364
579
 
365
- `Slack::RealTime::Client` needs help from a concurrency library and supports [Faye::WebSocket](https://github.com/faye/faye-websocket-ruby) with [Eventmachine](https://github.com/eventmachine/eventmachine) and [Celluloid](https://github.com/celluloid/celluloid). It will auto-detect one or the other depending on the gems in your Gemfile, but you can also set concurrency explicitly.
580
+ client.start_async
581
+ ```
582
+
583
+ ##### Async
584
+
585
+ Add `async-websocket` to your Gemfile.
586
+
587
+ ```
588
+ gem 'async-websocket'
589
+ ```
590
+
591
+ See a fully working example in [examples/hi_real_time_async_async](examples/hi_real_time_async_async/hi.rb).
592
+
593
+ ### Events API
594
+
595
+ This library provides limited support for the [Slack Events API](https://api.slack.com/events-api).
596
+
597
+ #### Configuring Slack::Events
598
+
599
+ You can configure Events support globally.
366
600
 
367
601
  ```ruby
368
- Slack::RealTime.configure do |config|
369
- config.concurrency = Slack::RealTime::Concurrency::Eventmachine
602
+ Slack::Events.configure do |config|
603
+ config.signing_secret = 'secret'
370
604
  end
371
605
  ```
372
606
 
373
- Use `client.start_async` instead of `client.start!`. A good example of such application is [slack-bot-server](https://github.com/dblock/slack-bot-server).
607
+ The following settings are supported.
608
+
609
+ setting | description
610
+ ----------------------|---------------------------------------------------------------------------------------------------
611
+ signing_secret | Slack signing secret, defaults is `ENV['SLACK_SIGNING_SECRET']`.
612
+ signature_expires_in | Signature expiration window in seconds, default is `300`.
613
+
614
+ #### Verifying the Request Signature
615
+
616
+ Slack signs its requests using a secret that's unique to your app. Verify incoming HTTP requests as follows.
374
617
 
375
618
  ```ruby
376
- client = Slack::RealTime::Client.new
619
+ slack_request = Slack::Events::Request.new(http_request)
620
+ slack_request.verify!
621
+ ```
377
622
 
378
- client.start_async
623
+ To specify secrets on a per-request basis:
624
+ ```ruby
625
+ Slack::Events::Request.new(http_request,
626
+ signing_secret: signing_secret,
627
+ signature_expires_in: signature_expires_in)
379
628
  ```
380
629
 
381
- ##### Faye::Websocket with Eventmachine
630
+ The `verify!` call may raise `Slack::Events::Request::MissingSigningSecret`, `Slack::Events::Request::InvalidSignature` or `Slack::Events::Request::TimestampExpired` errors.
382
631
 
383
- Add the following to your Gemfile.
632
+ ### Message Handling
384
633
 
385
- ```
386
- gem 'faye-websocket'
634
+ All text in Slack uses the same [system of formatting and escaping](https://api.slack.com/docs/formatting): chat messages, direct messages, file comments, etc. [Slack::Messages::Formatting](lib/slack/messages/formatting.rb) provides convenience methods to format and parse messages.
635
+
636
+ #### Formatting Messages
637
+
638
+ `Slack::Messages::Formatting` provides a number of methods for formatting objects that you can then embed in outgoing messages.
639
+
640
+ ##### Date and Time Formatting
641
+
642
+ You can embed a pre-formatted date in a message as a string like any other text, but using Slack's date formatting allows you to display dates based on user preferences for dates and times, incorporating users' local time zones, and optionally using relative values like "yesterday", "today", or "tomorrow" when appropriate.
643
+
644
+ ```ruby
645
+ date = Time.now
646
+
647
+ # Display date as `YYYY-MM-DD HH:MM:SS`
648
+ Slack::Messages::Formatting.date(date)
649
+ # => "<!date^1688150386^{date_num} {time_secs}|2023-06-30 18:39:46 +0000>"
650
+
651
+ # Specify a different format
652
+ # See https://api.slack.com/reference/surfaces/formatting#date-formatting for supported formats
653
+ Slack::Messages::Formatting.date(date, format: 'date_long_pretty')
654
+ # => "<!date^1688150386^date_long_pretty|2023-06-30 18:39:46 +0000>"
655
+
656
+ # Link your timestamp to a fully qualified URL
657
+ Slack::Messages::Formatting.date(date, link: 'https://media.giphy.com/media/AcfTF7tyikWyroP0x7/giphy.gif')
658
+ # => "<!date^1688150386^{date_num} {time_secs}^https://media.giphy.com/media/AcfTF7tyikWyroP0x7/giphy.gif|2023-06-30 18:39:46 +0000>"
659
+
660
+ # Specify custom fallback text to use if the client is unable to process the date
661
+ Slack::Messages::Formatting.date(date, text: 'party time!')
662
+ # => "<!date^1688150386^{date_num} {time_secs}|party time!>"
387
663
  ```
388
664
 
389
- See a fully working example in [examples/hi_real_time_async_eventmachine](examples/hi_real_time_async_eventmachine/hi.rb).
665
+ ##### Channel ID Formatting
390
666
 
391
- ##### Celluloid
667
+ If you already know the channel name you can just embed it in the message as `#some-channel`, but if you only have the ID you can embed it using special syntax which Slack will display as the channel name (while respecting channel visibility).
392
668
 
393
- Add the following to your Gemfile.
669
+ ```ruby
670
+ channel_id = 'C0000000001'
671
+ Slack::Messages::Formatting.channel_link(channel_id)
672
+ # => "<#C0000000001>"
673
+ ```
674
+
675
+ ##### User ID Formatting
394
676
 
677
+ If you already know the user name you can just embed it in the message as `@some_username`, but if you only have the ID you can embed it using special syntax which Slack will display as the user name.
678
+
679
+ ```ruby
680
+ user_id = 'U0000000001'
681
+ Slack::Messages::Formatting.user_link(user_id)
682
+ # => "<@U0000000001>"
395
683
  ```
396
- gem 'celluloid-io', require: ['celluloid/current', 'celluloid/io']
684
+
685
+ ##### Group ID Formatting
686
+
687
+ If you already know the group name you can just embed it in the message as `@some_group`, but if you only have the ID you can embed it using special syntax which Slack will display as the group name.
688
+
689
+ ```ruby
690
+ group_id = 'S0000000001'
691
+ Slack::Messages::Formatting.group_link(group_id)
692
+ # => "<!subteam^S0000000001>"
397
693
  ```
398
694
 
399
- See a fully working example in [examples/hi_real_time_async_celluloid](examples/hi_real_time_async_celluloid/hi.rb).
695
+ ##### URL Formatting
400
696
 
401
- Require
697
+ Slack will automatically parse fully qualified URLs in messages, but you need special formatting to embed a link with different text.
402
698
 
403
- ### Message Parsing
699
+ ```ruby
700
+ text = 'party time'
701
+ url = 'https://media.giphy.com/media/AcfTF7tyikWyroP0x7/giphy.gif'
702
+ Slack::Messages::Formatting.url_link(text, url)
703
+ # => "<https://media.giphy.com/media/AcfTF7tyikWyroP0x7/giphy.gif|party time>"
704
+ ```
705
+
706
+ ##### Markdown Formatting
404
707
 
405
- All text in Slack uses the same [system of escaping](https://api.slack.com/docs/formatting): chat messages, direct messages, file comments, etc. Use [Slack::Messages::Formatting](lib/slack/messages/formatting.rb) to unescape incoming messages. This comes handy, for example, you want to treat all input to a real time bot as plain text.
708
+ Slack uses a mishmash of regular markdown formatting with its own syntax. Some features like headings aren't supported and will be left as-is, but others like bold, strikethrough, and links are converted.
709
+
710
+ ```ruby
711
+ text = """
712
+ ## A heading
713
+ **Bold text**
714
+ ~~Strikethrough text~~
715
+ _Italic text_
716
+ [A link](https://example.com)
717
+ `code`
718
+ """
719
+ Slack::Messages::Formatting.markdown(text)
720
+ # => """
721
+ # ## A heading
722
+ # *Bold text*
723
+ # ~Strikethrough text~
724
+ # _Italic text_
725
+ # <https://example.com|A link>
726
+ # `code`
727
+ # """
728
+ ```
729
+
730
+ #### Parsing Messages
731
+
732
+ `Slack::Messages::Formatting` also provides ways to escape or unescape messages. This comes handy, for example, you want to treat all input to a real time bot as plain text.
733
+
734
+ ##### Unescaping Message Content
406
735
 
407
736
  ```ruby
408
- Slack::Messages::Formatting.unescape('Hello &amp; &lt;world&gt;'))
737
+ Slack::Messages::Formatting.unescape('Hello &amp; &lt;world&gt;')
409
738
  # => 'Hello & <world>'
410
- Slack::Messages::Formatting.unescape('Hey <@U024BE7LH|bob>, did you see my file?'))
739
+ Slack::Messages::Formatting.unescape('Hey <@U024BE7LH|bob>, did you see my file?')
411
740
  # => 'Hey @bob, did you see my file?'
412
- Slack::Messages::Formatting.unescape('Hey <@U02BEFY4U>'))
741
+ Slack::Messages::Formatting.unescape('Hey <@U02BEFY4U>')
413
742
  # => 'Hey @U02BEFY4U'
414
- Slack::Messages::Formatting.unescape('This message contains a URL <http://foo.com/>'))
743
+ Slack::Messages::Formatting.unescape('This message contains a URL <http://foo.com/>')
415
744
  # => 'This message contains a URL http://foo.com/'
416
- Slack::Messages::Formatting.unescape('So does this one: <http://www.foo.com|www.foo.com>'))
745
+ Slack::Messages::Formatting.unescape('So does this one: <http://www.foo.com|www.foo.com>')
417
746
  # => 'So does this one: www.foo.com'
418
- Slack::Messages::Formatting.unescape('<mailto:bob@example.com|Bob>'))
747
+ Slack::Messages::Formatting.unescape('<mailto:bob@example.com|Bob>')
419
748
  # => 'Bob'
420
- Slack::Messages::Formatting.unescape('Hello <@U123|bob>, say hi to <!everyone> in <#C1234|general>'))
749
+ Slack::Messages::Formatting.unescape('Hello <@U123|bob>, say hi to <!everyone> in <#C1234|general>')
421
750
  # => 'Hello @bob, say hi to @everyone in #general'
422
- Slack::Messages::Formatting.unescape('Hello <@U123|bob> &gt; file.txt'))
751
+ Slack::Messages::Formatting.unescape('Hello <@U123|bob> &gt; file.txt')
423
752
  # => 'Hello @bob > file.txt'
424
- Slack::Messages::Formatting.unescape('“hello”'))
753
+ Slack::Messages::Formatting.unescape('“hello”')
425
754
  # => '"hello"'
426
- Slack::Messages::Formatting.unescape('‘hello’'))
755
+ Slack::Messages::Formatting.unescape('‘hello’')
427
756
  # => "'hello'"
428
757
  ```
429
758
 
759
+ ##### Escaping Message Content
760
+
761
+ ```ruby
762
+ Slack::Messages::Formatting.escape('Hello & <world>')
763
+ # => 'Hello &amp; &lt;world&gt;'
764
+ ```
765
+
430
766
  ### Command-Line Client
431
767
 
432
768
  The slack command-line client returns JSON data from the Slack API.
@@ -446,17 +782,10 @@ $ slack chat postMessage --text="hello world" --channel="#general"
446
782
  {"ok":true,"channel":"...","ts":"...","message":{"text":"hello world","username":"bot","type":"message","subtype":"bot_message","ts":"..."}}
447
783
  ```
448
784
 
449
- #### Get Channel Id
450
-
451
- ```
452
- $ slack channels id --channel=#general
453
- {"ok":true,"channel":{"id":"C04KB5X4D"}}
454
- ```
455
-
456
785
  #### Get Channel Info
457
786
 
458
787
  ```
459
- $ slack channels info --channel=#general
788
+ $ slack conversations info --channel=#general
460
789
  {"ok":true,"channel":{"id":"C04KB5X4D","name":"general", ...}}
461
790
  ```
462
791
 
@@ -478,16 +807,26 @@ $ slack users list | jq '.members | map({(.id): .name})'
478
807
 
479
808
  See `slack help` for a complete command-line reference.
480
809
 
810
+ ## Enterprise Support
811
+
812
+ Available as part of the Tidelift Subscription.
813
+
814
+ The maintainers of slack-ruby-client are working with Tidelift to deliver commercial support and maintenance. Save time, reduce risk, and improve code health, while paying the maintainers of slack-ruby-client. Click [here](https://tidelift.com/subscription/request-a-demo?utm_source=rubygems-slack-ruby-client&utm_medium=referral&utm_campaign=enterprise) for more details.
815
+
481
816
  ## History
482
817
 
483
818
  This gem is based on [slack-ruby-gem](https://github.com/aki017/slack-ruby-gem), but it more clearly separates the Web and RTM APIs, is more thoroughly tested and is in active development.
484
819
 
820
+ ## Security
821
+
822
+ See [SECURITY](SECURITY.md).
823
+
485
824
  ## Contributing
486
825
 
487
826
  See [CONTRIBUTING](CONTRIBUTING.md).
488
827
 
489
828
  ## Copyright and License
490
829
 
491
- Copyright (c) 2015-2016, [Daniel Doubrovkine](https://twitter.com/dblockdotorg), [Artsy](https://www.artsy.net) and [Contributors](CHANGELOG.md).
830
+ Copyright (c) 2015-2021, [Daniel Doubrovkine](https://twitter.com/dblockdotorg), [Artsy](https://www.artsy.net) and [Contributors](CHANGELOG.md).
492
831
 
493
832
  This project is licensed under the [MIT License](LICENSE.md).