slack-ruby-client 2.5.2 → 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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +2 -0
  3. data/.github/workflows/update_api.yml +1 -1
  4. data/.rubocop_todo.yml +22 -13
  5. data/CHANGELOG.md +15 -0
  6. data/CONTRIBUTING.md +1 -1
  7. data/Gemfile +3 -0
  8. data/README.md +44 -17
  9. data/bin/commands/admin_conversations.rb +12 -1
  10. data/bin/commands/admin_users.rb +1 -1
  11. data/bin/commands/assistant_search.rb +27 -0
  12. data/bin/commands/canvases.rb +1 -0
  13. data/bin/commands/chat.rb +1 -0
  14. data/bin/commands/conversations_canvases.rb +1 -0
  15. data/bin/commands/files.rb +1 -0
  16. data/bin/commands/functions_distributions_permissions.rb +6 -4
  17. data/bin/commands/usergroups.rb +0 -1
  18. data/examples/files_upload_v2/files_upload_v2.rb +8 -0
  19. data/lib/slack/events/request.rb +3 -1
  20. data/lib/slack/messages/formatting.rb +8 -0
  21. data/lib/slack/utils/security.rb +44 -0
  22. data/lib/slack/version.rb +1 -1
  23. data/lib/slack/web/api/endpoints/admin_conversations.rb +18 -1
  24. data/lib/slack/web/api/endpoints/admin_users.rb +1 -1
  25. data/lib/slack/web/api/endpoints/assistant_search.rb +44 -0
  26. data/lib/slack/web/api/endpoints/canvases.rb +2 -0
  27. data/lib/slack/web/api/endpoints/chat.rb +2 -0
  28. data/lib/slack/web/api/endpoints/conversations.rb +0 -1
  29. data/lib/slack/web/api/endpoints/conversations_canvases.rb +2 -0
  30. data/lib/slack/web/api/endpoints/files.rb +3 -0
  31. data/lib/slack/web/api/endpoints/functions_distributions_permissions.rb +6 -2
  32. data/lib/slack/web/api/endpoints/usergroups.rb +0 -2
  33. data/lib/slack/web/api/endpoints.rb +2 -0
  34. data/lib/slack/web/api/errors.rb +34 -2
  35. data/lib/slack/web/api/helpers/files.rb +32 -22
  36. data/lib/slack/web/api/mixins/conversations.id.rb +23 -1
  37. data/lib/slack/web/api/mixins/ids.id.rb +3 -3
  38. data/lib/slack/web/api/mixins/users.id.rb +16 -1
  39. data/lib/slack/web/config.rb +4 -0
  40. data/lib/slack-ruby-client.rb +3 -1
  41. data/slack-ruby-client.gemspec +1 -1
  42. metadata +7 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a618c19aef053b39b70616b4c2965e367b7c7a9607091501626ca0e8c1112d49
4
- data.tar.gz: 0f19c3999ef2b3129c654baa30517c0863fe8b719e14f922d8106a529395e2e5
3
+ metadata.gz: c51153c945fdc89a1aa46ba02eb49256f7f2978277901f4d95e68c4d92197856
4
+ data.tar.gz: 9c450898f129249fcd6e2ab448830ba6e0f118e74c8af2f3e3e26e9419cc16ea
5
5
  SHA512:
6
- metadata.gz: dfb4b2f108f3c66a7f8738cccb2a3831f6b8443fec90f14163caa9875febb581eac5771d4dfdde784f3cfc4ae7d8857de873b6b9603136074bf1eb1a5837dbc8
7
- data.tar.gz: 3bf0ad65a3fbe56ac30fc304671b17ef982e1b874457ce4721f81c1767c8698e53373a9e38d3a9cdb11a9b600287109dc15f420607bdd38e194b507f416b9845
6
+ metadata.gz: e1df2c875eb165a043823bd911fc2ac585693dc625bd32070081d01a4cbd4667c32252d287f14960a72266e28f2cd9787b59ef34101fb076e551448094bc1385
7
+ data.tar.gz: c5bce1883b654790df7992f8dec417cf3976ef210f0d35dd219de54666ec556c957fec9762a094149269c3d195f1c0333fab129ba10320d3f959448924bb42d0
@@ -30,6 +30,7 @@ jobs:
30
30
  with:
31
31
  ruby-version: ${{ matrix.entry.ruby }}
32
32
  bundler-cache: true # 'bundle install' and cache gems
33
+ continue-on-error: ${{ matrix.entry.ignore || false }}
33
34
  - name: Run Tests
34
35
  continue-on-error: ${{ matrix.entry.ignore || false }}
35
36
  env:
@@ -41,6 +42,7 @@ jobs:
41
42
  parallel: true
42
43
  github-token: ${{ secrets.GITHUB_TOKEN }}
43
44
  flag-name: run-${{ matrix.entry.ruby }}${{ matrix.entry.concurrency && '-'}}${{ matrix.entry.concurrency }}
45
+ allow-empty: ${{ matrix.entry.ignore || false }}
44
46
 
45
47
  finish:
46
48
  name: coveralls
@@ -2,7 +2,7 @@ name: Update API
2
2
  on:
3
3
  workflow_dispatch:
4
4
  schedule:
5
- - cron: "15 23 * * *"
5
+ - cron: "15 23 * * 1"
6
6
  jobs:
7
7
  update-api:
8
8
  if: ${{ github.repository == 'slack-ruby/slack-ruby-client' }}
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2025-02-11 15:48:56 UTC using RuboCop version 1.26.1.
3
+ # on 2025-07-19 11:04:04 UTC using RuboCop version 1.26.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -47,17 +47,17 @@ Lint/RedundantCopDisableDirective:
47
47
  # Offense count: 13
48
48
  # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
49
49
  Metrics/AbcSize:
50
- Max: 58
50
+ Max: 67
51
51
 
52
52
  # Offense count: 6
53
53
  # Configuration parameters: IgnoredMethods.
54
54
  Metrics/CyclomaticComplexity:
55
- Max: 11
55
+ Max: 15
56
56
 
57
- # Offense count: 15
57
+ # Offense count: 17
58
58
  # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
59
59
  Metrics/MethodLength:
60
- Max: 35
60
+ Max: 45
61
61
 
62
62
  # Offense count: 1
63
63
  # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
@@ -67,12 +67,13 @@ Metrics/ParameterLists:
67
67
  # Offense count: 3
68
68
  # Configuration parameters: IgnoredMethods.
69
69
  Metrics/PerceivedComplexity:
70
- Max: 12
70
+ Max: 17
71
71
 
72
- # Offense count: 1
72
+ # Offense count: 2
73
73
  # Configuration parameters: MinSize.
74
74
  Performance/CollectionLiteralInLoop:
75
75
  Exclude:
76
+ - 'lib/slack/web/api/helpers/files.rb'
76
77
  - 'spec/slack/web/api/endpoints/custom/files_spec.rb'
77
78
 
78
79
  # Offense count: 1
@@ -93,20 +94,20 @@ Performance/StringInclude:
93
94
  Exclude:
94
95
  - 'lib/tasks/web.rake'
95
96
 
96
- # Offense count: 9
97
+ # Offense count: 10
97
98
  # This cop supports safe auto-correction (--auto-correct).
98
99
  RSpec/ContextMethod:
99
100
  Exclude:
100
101
  - 'spec/slack/messages/formatting_spec.rb'
101
102
  - 'spec/slack/web/api/mixins/users_spec.rb'
102
103
 
103
- # Offense count: 84
104
+ # Offense count: 86
104
105
  # Configuration parameters: Prefixes.
105
106
  # Prefixes: when, with, without
106
107
  RSpec/ContextWording:
107
108
  Enabled: false
108
109
 
109
- # Offense count: 72
110
+ # Offense count: 75
110
111
  # Configuration parameters: CountAsOne.
111
112
  RSpec/ExampleLength:
112
113
  Max: 18
@@ -117,13 +118,13 @@ RSpec/ExampleLength:
117
118
  RSpec/FilePath:
118
119
  Enabled: false
119
120
 
120
- # Offense count: 74
121
+ # Offense count: 86
121
122
  # Configuration parameters: .
122
123
  # SupportedStyles: have_received, receive
123
124
  RSpec/MessageSpies:
124
125
  EnforcedStyle: receive
125
126
 
126
- # Offense count: 97
127
+ # Offense count: 103
127
128
  RSpec/MultipleExpectations:
128
129
  Max: 5
129
130
 
@@ -151,7 +152,7 @@ RSpec/StubbedMock:
151
152
  - 'spec/slack/web/api/pagination/cursor_spec.rb'
152
153
  - 'spec/slack/web/client_spec.rb'
153
154
 
154
- # Offense count: 2
155
+ # Offense count: 14
155
156
  RSpec/SubjectStub:
156
157
  Exclude:
157
158
  - 'spec/slack/web/api/mixins/conversations_spec.rb'
@@ -232,6 +233,14 @@ Style/OptionalBooleanParameter:
232
233
  Exclude:
233
234
  - 'spec/support/queue_with_timeout.rb'
234
235
 
236
+ # Offense count: 1
237
+ # This cop supports safe auto-correction (--auto-correct).
238
+ # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods.
239
+ # AllowedMethods: present?, blank?, presence, try, try!
240
+ Style/SafeNavigation:
241
+ Exclude:
242
+ - 'lib/slack/web/api/helpers/files.rb'
243
+
235
244
  # Offense count: 1
236
245
  # This cop supports unsafe auto-correction (--auto-correct-all).
237
246
  Style/SlicingWithRange:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ### 2.7.0 (2025/07/20)
2
+
3
+ * [#554](https://github.com/slack-ruby/slack-ruby-client/pull/557): Require Faraday >= 2.0.1 - [@anrichvs](https://github.com/AnrichVS).
4
+ * [#559](https://github.com/slack-ruby/slack-ruby-client/pull/559): Enable name-to-id translation of non-public channels - [@eizengan](https://github.com/eizengan).
5
+ * [#560](https://github.com/slack-ruby/slack-ruby-client/pull/560): Name-to-id translation can supply all sensible list options - [@eizengan](https://github.com/eizengan).
6
+ * [#561](https://github.com/slack-ruby/slack-ruby-client/issues/563): Raise InvalidSignature when verifying a request without a signature - [@wesleyjellis](https://github.com/wesleyjellis).
7
+ * [#567](https://github.com/slack-ruby/slack-ruby-client/pull/567): Add support for multiple files in `files_upload_v2` - [@dblock](https://github.com/dblock).
8
+
9
+ ### 2.6.0 (2025/05/24)
10
+
11
+ * [#549](https://github.com/slack-ruby/slack-ruby-client/pull/549): Add group ID formatting support for message mentions - [@n0h0](https://github.com/n0h0).
12
+ * [#553](https://github.com/slack-ruby/slack-ruby-client/pull/553): Use `secure_compare` during signature verification - [@hieuk09](https://github.com/hieuk09).
13
+ * [#555](https://github.com/slack-ruby/slack-ruby-client/pull/555): Make page size in resolving IDs configurable - [@eizengan](https://github.com/eizengan).
14
+ * [#547](https://github.com/slack-ruby/slack-ruby-client/pull/547): Update API from [slack-api-ref@1ee282e](https://github.com/slack-ruby/slack-api-ref/commit/1ee282e) - [@slack-ruby-ci-bot](https://github.com/apps/slack-ruby-ci-bot).
15
+
1
16
  ### 2.5.2 (2025/02/19)
2
17
 
3
18
  * [#548](https://github.com/slack-ruby/slack-ruby-client/pull/548): Fix: `files_upload_v2` with `#channel` - [@dblock](https://github.com/dblock).
data/CONTRIBUTING.md CHANGED
@@ -27,7 +27,7 @@ bundle exec rake
27
27
 
28
28
  ### Run Examples in Development
29
29
 
30
- Sign up for Slack, create a private Slack team for yourself, then [generate an API token](https://api.slack.com/tutorials/tracks/getting-a-token) for your app and use it for some interactions.
30
+ Sign up for Slack, create a private Slack team for yourself, then [generate an API token](https://api.slack.com/tutorials/tracks/getting-a-token) for your app and use it for some interactions. To get a token you will need to install the app in a workspace, and use the "User OAuth Token" from installed app settings.
31
31
 
32
32
  Try running the examples in the [examples](examples) directory.
33
33
 
data/Gemfile CHANGED
@@ -14,9 +14,12 @@ end
14
14
 
15
15
  group :test do
16
16
  gem 'activesupport'
17
+ gem 'base64'
18
+ gem 'bigdecimal'
17
19
  gem 'erubis'
18
20
  gem 'faraday-typhoeus'
19
21
  gem 'json-schema'
22
+ gem 'mutex_m'
20
23
  gem 'racc'
21
24
  gem 'rake', '~> 13'
22
25
  gem 'rspec'
data/README.md CHANGED
@@ -4,7 +4,6 @@ Slack Ruby Client
4
4
  [![Gem Version](https://badge.fury.io/rb/slack-ruby-client.svg)](http://badge.fury.io/rb/slack-ruby-client)
5
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
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
- [![Code Climate](https://codeclimate.com/github/slack-ruby/slack-ruby-client/badges/gpa.svg)](https://codeclimate.com/github/slack-ruby/slack-ruby-client)
8
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)
9
8
 
10
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).
@@ -57,6 +56,7 @@ A Ruby client for the Slack [Web](https://api.slack.com/web), [RealTime Messagin
57
56
  - [Date and Time Formatting](#date-and-time-formatting)
58
57
  - [Channel ID Formatting](#channel-id-formatting)
59
58
  - [User ID Formatting](#user-id-formatting)
59
+ - [Group ID Formatting](#group-id-formatting)
60
60
  - [URL Formatting](#url-formatting)
61
61
  - [Markdown Formatting](#markdown-formatting)
62
62
  - [Parsing Messages](#parsing-messages)
@@ -81,7 +81,7 @@ A Ruby client for the Slack [Web](https://api.slack.com/web), [RealTime Messagin
81
81
 
82
82
  ## Stable Release
83
83
 
84
- You're reading the documentation for the **stable** release of slack-ruby-client, v2.5.2. 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.
85
85
 
86
86
  ## Installation
87
87
 
@@ -173,12 +173,14 @@ Upload files with [sequenced API calls](https://api.slack.com/messaging/files#up
173
173
 
174
174
  This library provides a helper method `files_upload_v2` that wraps the three separate API calls.
175
175
 
176
+ Upload a single file.
177
+
176
178
  ```ruby
177
179
  client.files_upload_v2(
178
180
  # required options
179
181
  filename: 'results.pdf', # this is used for the file title, unless a :title option is provided
180
182
  content: File.read('/users/me/results.pdf'), # the string contents of the file
181
-
183
+
182
184
  # optional options
183
185
  channels: ['C000000', 'C000001'], # channel IDs to share the file in (:channel_id, :channel, or :channels are all supported)
184
186
  initial_comment: 'Sharing the Q1 results :tada:', # the message that is included with the file share thread
@@ -188,6 +190,19 @@ client.files_upload_v2(
188
190
  )
189
191
  ```
190
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
+
191
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.
192
207
 
193
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).
@@ -280,20 +295,22 @@ client = Slack::Web::Client.new(user_agent: 'Slack Ruby Client/1.0')
280
295
 
281
296
  The following settings are supported.
282
297
 
283
- setting | description
284
- --------------------|-------------------------------------------------------------------------------------------------
285
- token | Slack API token.
286
- user_agent | User-agent, defaults to _Slack Ruby Client/version_.
287
- proxy | Optional HTTP proxy.
288
- ca_path | Optional SSL certificates path.
289
- ca_file | Optional SSL certificates file.
290
- endpoint | Slack endpoint, default is _https://slack.com/api_.
291
- logger | Optional `Logger` instance that logs HTTP requests.
292
- timeout | Optional open/read timeout in seconds.
293
- open_timeout | Optional connection open timeout in seconds.
294
- default_page_size | Optional page size for paginated requests, default is _100_.
295
- default_max_retries | Optional number of retries for paginated requests, default is _100_.
296
- adapter | Optional HTTP adapter to use, defaults to `Faraday.default_adapter`.
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`.
297
314
 
298
315
  You can also pass request options, including `timeout` and `open_timeout` into individual calls.
299
316
 
@@ -665,6 +682,16 @@ Slack::Messages::Formatting.user_link(user_id)
665
682
  # => "<@U0000000001>"
666
683
  ```
667
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>"
693
+ ```
694
+
668
695
  ##### URL Formatting
669
696
 
670
697
  Slack will automatically parse fully qualified URLs in messages, but you need special formatting to embed a link with different text.
@@ -75,6 +75,17 @@ module Slack
75
75
  end
76
76
  end
77
77
 
78
+ g.desc 'Create a Salesforce channel for the corresponding object provided.'
79
+ g.long_desc %( Create a Salesforce channel for the corresponding object provided. )
80
+ g.command 'createForObjects' do |c|
81
+ c.flag 'object_id', desc: 'Object / Record ID (15 or 18 digit accepted). See here for how to look up an ID.'
82
+ c.flag 'salesforce_org_id', desc: 'Salesforce org ID (15 or 18 digit accepted). See here for how to look up Salesforce org ID.'
83
+ c.flag 'invite_object_team', desc: 'Optional flag to add all team members related to the object to the newly created Salesforce channel. When true, adds a maximum of 100 team members to the channel.'
84
+ c.action do |_global_options, options, _args|
85
+ puts JSON.dump(@client.admin_conversations_createForObjects(options))
86
+ end
87
+ end
88
+
78
89
  g.desc 'Delete a public or private channel.'
79
90
  g.long_desc %( Delete a public or private channel. )
80
91
  g.command 'delete' do |c|
@@ -219,7 +230,7 @@ module Slack
219
230
  c.flag 'channel_id', desc: 'The encoded channel_id to add or remove to workspaces.'
220
231
  c.flag 'org_channel', desc: 'True if channel has to be converted to an org channel.'
221
232
  c.flag 'target_team_ids', desc: 'A comma-separated list of workspaces to which the channel should be shared. Not required if the channel is being shared org-wide.'
222
- c.flag 'team_id', desc: 'The workspace to which the channel belongs. Omit this argument if the channel is a cross-workspace shared channel.'
233
+ c.flag 'team_id', desc: 'The workspace to which the channel belongs if the channel is a local workspace channel. Omit this argument if the channel is a cross-workspace or org-wide shared channel.'
223
234
  c.action do |_global_options, options, _args|
224
235
  puts JSON.dump(@client.admin_conversations_setTeams(options))
225
236
  end
@@ -44,7 +44,7 @@ module Slack
44
44
  c.flag 'include_deactivated_user_workspaces', desc: 'Only applies with org token and no team_id. If true, return workspaces for a user even if they may be deactivated on them. If false, return workspaces for a user only when user is active on them. Default is false.'
45
45
  c.flag 'is_active', desc: 'If true, only active users will be returned. If false, only deactivated users will be returned. Default is true.'
46
46
  c.flag 'limit', desc: 'Limit for how many users to be retrieved per page.'
47
- c.flag 'team_id', desc: 'The ID (T1234) of the workspace. The team_id is required if you use an org-level token.'
47
+ c.flag 'team_id', desc: 'The ID (T1234) of a workspace. Filters results to just the specified workspace.'
48
48
  c.action do |_global_options, options, _args|
49
49
  puts JSON.dump(@client.admin_users_list(options))
50
50
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+ # This file was auto-generated by lib/tasks/web.rake
3
+
4
+ module Slack
5
+ module Cli
6
+ class App
7
+ desc 'AssistantSearch methods.'
8
+ command 'assistant_search' do |g|
9
+ g.desc 'Searches messages across your Slack organization—perfect for broad, specific, and real-time data retrieval.'
10
+ g.long_desc %( Searches messages across your Slack organization—perfect for broad, specific, and real-time data retrieval. )
11
+ g.command 'context' do |c|
12
+ c.flag 'query', desc: 'User prompt or search query.'
13
+ c.flag 'action_token', desc: 'Send action_token as received in a message event.'
14
+ c.flag 'channel_types', desc: 'Mix and match channel types by providing a comma-separated list of any combination of public_channel, private_channel, mpim, im.'
15
+ c.flag 'content_types', desc: 'Content types to include, a comma-separated list of any combination of messages, files.'
16
+ c.flag 'context_channel_id', desc: 'Context channel ID to support scoping the search when applicable.'
17
+ c.flag 'cursor', desc: 'The cursor returned by the API. Leave this blank for the first request, and use this to get the next page of results.'
18
+ c.flag 'include_bots', desc: 'If you want the results to include bots.'
19
+ c.flag 'limit', desc: 'Number of results to return, up to a max of 20. Defaults to 20.'
20
+ c.action do |_global_options, options, _args|
21
+ puts JSON.dump(@client.assistant_search_context(options))
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -9,6 +9,7 @@ module Slack
9
9
  g.desc 'Create canvas for a user'
10
10
  g.long_desc %( Create canvas for a user )
11
11
  g.command 'create' do |c|
12
+ c.flag 'channel_id', desc: 'Channel ID of the channel the canvas will be tabbed in. This is a required field for free teams.'
12
13
  c.flag 'document_content', desc: 'Structure describing the type and value of the content to create.'
13
14
  c.flag 'title', desc: 'Title of the newly created canvas.'
14
15
  c.action do |_global_options, options, _args|
data/bin/commands/chat.rb CHANGED
@@ -87,6 +87,7 @@ module Slack
87
87
  c.flag 'attachments', desc: 'A JSON-based array of structured attachments, presented as a URL-encoded string.'
88
88
  c.flag 'blocks', desc: 'A JSON-based array of structured blocks, presented as a URL-encoded string.'
89
89
  c.flag 'text', desc: 'How this field works and whether it is required depends on other fields you use in your API call. See below for more detail.'
90
+ c.flag 'agent_message_source_type', desc: 'Identify how the message was posted for agentforce BE logging.'
90
91
  c.flag 'as_user', desc: '(Legacy) Pass true to post the message as the authed user instead of as a bot. Defaults to false. Can only be used by classic apps. See legacy as_user parameter below.'
91
92
  c.flag 'icon_emoji', desc: 'Emoji to use as the icon for this message. Overrides icon_url.'
92
93
  c.flag 'icon_url', desc: 'URL to an image to use as the icon for this message.'
@@ -11,6 +11,7 @@ module Slack
11
11
  g.command 'create' do |c|
12
12
  c.flag 'channel_id', desc: 'Channel ID of the channel we create the channel canvas for.'
13
13
  c.flag 'document_content', desc: 'Structure describing the type and value of the content to create.'
14
+ c.flag 'title', desc: 'Title of the newly created canvas.'
14
15
  c.action do |_global_options, options, _args|
15
16
  puts JSON.dump(@client.conversations_canvases_create(options))
16
17
  end
@@ -10,6 +10,7 @@ module Slack
10
10
  g.long_desc %( Finishes an upload started with files.getUploadURLExternal )
11
11
  g.command 'completeUploadExternal' do |c|
12
12
  c.flag 'files', desc: 'Array of file ids and their corresponding (optional) titles.'
13
+ c.flag 'blocks', desc: 'A JSON-based array of structured rich text blocks, presented as a URL-encoded string. If the initial_comment field is provided, the blocks field is ignored.'
13
14
  c.flag 'channel_id', desc: 'Channel ID where the file will be shared. If not specified the file will be private.'
14
15
  c.flag 'channels', desc: 'Comma-separated string of channel IDs where the file will be shared.'
15
16
  c.flag 'initial_comment', desc: 'The message text introducing the file in specified channels.'
@@ -18,8 +18,8 @@ module Slack
18
18
  end
19
19
  end
20
20
 
21
- g.desc 'List the access type of a custom slack function and include the users with access if its permission_type is set to named_entities'
22
- g.long_desc %( List the access type of a custom slack function and include the users with access if its permission_type is set to named_entities )
21
+ g.desc 'List the access type of a custom slack function and include the users or team or org ids with access if its permission_type is set to named_entities'
22
+ g.long_desc %( List the access type of a custom slack function and include the users or team or org ids with access if its permission_type is set to named_entities )
23
23
  g.command 'list' do |c|
24
24
  c.flag 'function_app_id', desc: 'The encoded ID of the app.'
25
25
  c.flag 'function_callback_id', desc: "The callback ID defined in the function's definition file."
@@ -41,13 +41,15 @@ module Slack
41
41
  end
42
42
  end
43
43
 
44
- g.desc 'Set the access type of a custom slack function and define the users to be granted access if permission_type is set to named_entities'
45
- g.long_desc %( Set the access type of a custom slack function and define the users to be granted access if permission_type is set to named_entities )
44
+ g.desc 'Set the access type of a custom slack function and define the users or team or org ids to be granted access if permission_type is set to named_entities'
45
+ g.long_desc %( Set the access type of a custom slack function and define the users or team or org ids to be granted access if permission_type is set to named_entities )
46
46
  g.command 'set' do |c|
47
47
  c.flag 'permission_type', desc: 'The type of permission that defines how the function can be distributed.'
48
48
  c.flag 'function_app_id', desc: 'The encoded ID of the app.'
49
49
  c.flag 'function_callback_id', desc: "The callback ID defined in the function's definition file."
50
50
  c.flag 'function_id', desc: 'The encoded ID of the function.'
51
+ c.flag 'org_ids', desc: 'List of org IDs to allow for named_entities permission.'
52
+ c.flag 'team_ids', desc: 'List of team IDs to allow for named_entities permission.'
51
53
  c.flag 'user_ids', desc: 'List of encoded user IDs.'
52
54
  c.action do |_global_options, options, _args|
53
55
  puts JSON.dump(@client.functions_distributions_permissions_set(options))
@@ -51,7 +51,6 @@ module Slack
51
51
  c.flag 'include_disabled', desc: 'Include disabled User Groups.'
52
52
  c.flag 'include_users', desc: 'Include the list of users for each User Group.'
53
53
  c.flag 'team_id', desc: 'encoded team id to list user groups in, required if org token is used.'
54
- c.flag 'usergroup_id', desc: 'The id of the usergroup you would like to filter the results down to.'
55
54
  c.action do |_global_options, options, _args|
56
55
  puts JSON.dump(@client.usergroups_list(options))
57
56
  end
@@ -35,3 +35,11 @@ puts client.files_upload_v2(
35
35
  content: SecureRandom.hex,
36
36
  channel_id: channel_id
37
37
  ).files.first.permalink_public
38
+
39
+ client.files_upload_v2(
40
+ files: [
41
+ { filename: 'files_upload_v2_to_general_first_file.txt', content: SecureRandom.hex },
42
+ { filename: 'files_upload_v2_to_general_second_file.txt', content: SecureRandom.hex }
43
+ ],
44
+ channels: ['#general']
45
+ ).files.each { |file| puts file.permalink_public }
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Slack
3
4
  module Events
4
5
  class Request
@@ -54,12 +55,13 @@ module Slack
54
55
  # Returns true if the signature coming from Slack is valid.
55
56
  def valid?
56
57
  raise MissingSigningSecret unless signing_secret
58
+ raise InvalidSignature unless signature
57
59
 
58
60
  digest = OpenSSL::Digest.new('SHA256')
59
61
  signature_basestring = [version, timestamp, body].join(':')
60
62
  hex_hash = OpenSSL::HMAC.hexdigest(digest, signing_secret, signature_basestring)
61
63
  computed_signature = [version, hex_hash].join('=')
62
- computed_signature == signature
64
+ Utils::Security.secure_compare(computed_signature, signature)
63
65
  end
64
66
 
65
67
  # Validates the request signature and its expiration.
@@ -61,6 +61,14 @@ module Slack
61
61
  "<@#{user_id}>"
62
62
  end
63
63
 
64
+ #
65
+ # Embed a link to a group in a message by group ID
66
+ # @see https://api.slack.com/reference/surfaces/formatting#mentioning-groups
67
+ #
68
+ def group_link(group_id)
69
+ "<!subteam^#{group_id}>"
70
+ end
71
+
64
72
  #
65
73
  # Embed a URL with custom link text in a message
66
74
  # @see https://api.slack.com/reference/surfaces/formatting#linking-urls
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This module is copied from activesupport
4
+ # https://github.com/rails/rails/blob/3235827585d87661942c91bc81f64f56d710f0b2/activesupport/lib/active_support/security_utils.rb
5
+ module Slack
6
+ module Utils
7
+ # rubocop:disable Naming/MethodParameterName
8
+ module Security
9
+ # Constant time string comparison, for fixed length strings.
10
+ #
11
+ # The values compared should be of fixed length, such as strings
12
+ # that have already been processed by HMAC. Raises in case of length mismatch.
13
+
14
+ if defined?(OpenSSL.fixed_length_secure_compare)
15
+ def fixed_length_secure_compare(a, b)
16
+ OpenSSL.fixed_length_secure_compare(a, b)
17
+ end
18
+ else
19
+ def fixed_length_secure_compare(a, b)
20
+ raise ArgumentError, 'inputs must be of equal length' unless a.bytesize == b.bytesize
21
+
22
+ l = a.unpack "C#{a.bytesize}"
23
+
24
+ res = 0
25
+ b.each_byte { |byte| res |= byte ^ l.shift }
26
+ res.zero?
27
+ end
28
+ end
29
+ module_function :fixed_length_secure_compare
30
+
31
+ # Secure string comparison for strings of variable length.
32
+ #
33
+ # While a timing attack would not be able to discern the content of
34
+ # a secret compared via secure_compare, it is possible to determine
35
+ # the secret length. This should be considered when using secure_compare
36
+ # to compare weak, short secrets to user input.
37
+ def secure_compare(a, b)
38
+ a.bytesize == b.bytesize && fixed_length_secure_compare(a, b)
39
+ end
40
+ module_function :secure_compare
41
+ end
42
+ # rubocop:enable Naming/MethodParameterName
43
+ end
44
+ end
data/lib/slack/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Slack
3
- VERSION = '2.5.2'
3
+ VERSION = '2.7.0'
4
4
  end
@@ -104,6 +104,23 @@ module Slack
104
104
  post('admin.conversations.create', options)
105
105
  end
106
106
 
107
+ #
108
+ # Create a Salesforce channel for the corresponding object provided.
109
+ #
110
+ # @option options [string] :object_id
111
+ # Object / Record ID (15 or 18 digit accepted). See here for how to look up an ID.
112
+ # @option options [string] :salesforce_org_id
113
+ # Salesforce org ID (15 or 18 digit accepted). See here for how to look up Salesforce org ID.
114
+ # @option options [boolean] :invite_object_team
115
+ # Optional flag to add all team members related to the object to the newly created Salesforce channel. When true, adds a maximum of 100 team members to the channel.
116
+ # @see https://api.slack.com/methods/admin.conversations.createForObjects
117
+ # @see https://github.com/slack-ruby/slack-api-ref/blob/master/methods/admin.conversations/admin.conversations.createForObjects.json
118
+ def admin_conversations_createForObjects(options = {})
119
+ raise ArgumentError, 'Required arguments :object_id missing' if options[:object_id].nil?
120
+ raise ArgumentError, 'Required arguments :salesforce_org_id missing' if options[:salesforce_org_id].nil?
121
+ post('admin.conversations.createForObjects', options)
122
+ end
123
+
107
124
  #
108
125
  # Delete a public or private channel.
109
126
  #
@@ -338,7 +355,7 @@ module Slack
338
355
  # @option options [array] :target_team_ids
339
356
  # A comma-separated list of workspaces to which the channel should be shared. Not required if the channel is being shared org-wide.
340
357
  # @option options [Object] :team_id
341
- # The workspace to which the channel belongs. Omit this argument if the channel is a cross-workspace shared channel.
358
+ # The workspace to which the channel belongs if the channel is a local workspace channel. Omit this argument if the channel is a cross-workspace or org-wide shared channel.
342
359
  # @see https://api.slack.com/methods/admin.conversations.setTeams
343
360
  # @see https://github.com/slack-ruby/slack-api-ref/blob/master/methods/admin.conversations/admin.conversations.setTeams.json
344
361
  def admin_conversations_setTeams(options = {})
@@ -71,7 +71,7 @@ module Slack
71
71
  # @option options [integer] :limit
72
72
  # Limit for how many users to be retrieved per page.
73
73
  # @option options [Object] :team_id
74
- # The ID (T1234) of the workspace. The team_id is required if you use an org-level token.
74
+ # The ID (T1234) of a workspace. Filters results to just the specified workspace.
75
75
  # @see https://api.slack.com/methods/admin.users.list
76
76
  # @see https://github.com/slack-ruby/slack-api-ref/blob/master/methods/admin.users/admin.users.list.json
77
77
  def admin_users_list(options = {})