slack_line 1.2 → 1.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc23e7f575bc68df1c9824aacbde9b74050c14f82f765fc6929dc33ae909eccb
4
- data.tar.gz: 45e54647313e4c71a27de6c8bda77826deaf7704ac8a5680c1439c5015f9b50e
3
+ metadata.gz: 4cd84ee81b09ef89c3f46abcd5c595c29f3ced087632368f343aded9e20ac731
4
+ data.tar.gz: b17c80d061d6c9a72ae68321079414213905baaed8d9f2b976a95d3c8fcbc4cc
5
5
  SHA512:
6
- metadata.gz: 5c9d9e4c86c4ae41adac7a71a1044fe02aef53eaa823bc286862178b9fce6de8716d51a7833ed6ee118a550e29726358dd7b2a54df3bc78526074be65a125af4
7
- data.tar.gz: fc217ed772fbbcbf1a27aa0911d24f2ef716c4b6ffed127f2c0959329b5358e510654a4d313c9d42e8a0168a7b88fe3c5d253d46545775175bd3671c3e593a65
6
+ metadata.gz: 1ff7cc5918a5b9395496814e1bbdb8494449ec202fd08ebd584afb1991d532cd9c62581e3c561d95acf2f308c5abea071c6b697a2754204103c15b8da81ef790
7
+ data.tar.gz: bfb562e958ec5d2b71a1d8bb1c895f2fd34b4e1a6c9cd5d557de4454f584cd77cc95db2e916ebc9e769b79128d62ea10e71da8a6de75a686e1cf93ef82674e4f
@@ -8,7 +8,7 @@ jobs:
8
8
  strategy:
9
9
  fail-fast: false
10
10
  matrix:
11
- ruby-version: ['3.2', '3.3', '3.4', 'head']
11
+ ruby-version: ['3.2', '3.3', '3.4', '4.0', 'head']
12
12
 
13
13
  steps:
14
14
  - uses: actions/checkout@v4
data/CHANGELOG.md CHANGED
@@ -9,3 +9,24 @@ can do each of those things directly (for simpler messages).
9
9
  ## Version 1.1
10
10
 
11
11
  Fixed incorrect description/summary on gemspec.
12
+
13
+ ## Version 1.2
14
+
15
+ Added disk-caching for the users and groups lists, through the `cache_path` and
16
+ `cache_duration` config options and matching CLI flags. Added the
17
+ `slack_line_stateful_thread` script, and `content` and `update` on `SentThread`.
18
+
19
+ ## Version 1.3
20
+
21
+ `message` and `thread` now accept `to:`, as the README showed. Declared `reline`
22
+ as a runtime dependency, which fixes a warning or `LoadError` under Bundler on
23
+ Ruby 4.0. The invalid content error now lists the classes of the bad arguments.
24
+
25
+ ## Version 1.4
26
+
27
+ **Breaking change:** calling `text` more than once in a `section` now raises an
28
+ `ArgumentError`. It used to silently keep only the last text, because a Slack
29
+ section block has one text field. Use one `section` per text.
30
+
31
+ Fixed README examples that didn't run, including `context` inside a `section`,
32
+ which Slack doesn't allow.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2026 Eric Mueller
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -13,13 +13,15 @@ sent_message = SlackLine.message("Something happened!", to: "#general").post
13
13
 
14
14
  # Construct a more complex message, then send it
15
15
  msg = SlackLine.message do
16
+ context "Don't worry! If this message surprises you, context @foobar"
17
+
18
+ # Like a Slack section block, a section holds one text and one link
16
19
  section do
17
- context "Don't worry! If this message surprises you, context @foobar"
18
20
  text "A thing has happened"
19
- text "Yeah, it happened for sure"
20
21
  link "How bad?", problems_path(problem.id)
21
22
  end
22
23
 
24
+ text "Yeah, it happened for sure"
23
25
  text "More details.."
24
26
  end
25
27
  sent_message = msg.post(to: "#general")
@@ -51,7 +53,7 @@ To update a SentThread, you'll need to choose message:
51
53
  ```ruby
52
54
  sent_message.update "Edit: never mind, false alarm"
53
55
  sent_thread.first.update "Problem Resolved!"
54
- sent_thread.detect { |m| m =~ /Not yet safe/ }&.update do
56
+ sent_thread.detect { |m| m.content.to_s.include?("Not yet safe") }&.update do
55
57
  text "it's safe now"
56
58
  end
57
59
  ```
@@ -82,7 +84,8 @@ be set via ENV or `SlackLine.configure`:
82
84
  is posted, and after each non-thread message is posted.
83
85
  * `cache_path` or `SLACK_LINE_CACHE_PATH` - a directory path for
84
86
  disk-caching the users and groups lists fetched from the Slack API.
85
- When set, SlackLine will use the [lightly](https://github.com/DannyBen/lightly)
87
+ When set, SlackLine will use the
88
+ [lightly](https://github.com/DannyBen/lightly)
86
89
  gem to cache results to disk, which avoids redundant API calls across
87
90
  separate runs. Requires `lightly` to be installed as an optional
88
91
  dependency - if it is not available, a `DiskCaching::NoLightly` error
@@ -118,7 +121,7 @@ SlackLine methods dispatch to), but you can construct additional clients
118
121
  with their own configs easily:
119
122
 
120
123
  ```ruby
121
- Slackline.configure do |config|
124
+ SlackLine.configure do |config|
122
125
  config.slack_token = ENV["TOKEN"]
123
126
  config.default_channel = "#general"
124
127
  config.bot_name = "FooBot"
@@ -127,7 +130,7 @@ end
127
130
  # Now SlackLine.message (et al) will use SlackLine.client,
128
131
  # configured as above.
129
132
 
130
- BAR_SLACK = SlackLine::Client.new(default_channel: "#team-bar", bot_name: "BarBot")
133
+ BAR_SLACK = SlackLine::Client.new(SlackLine.configuration, default_channel: "#team-bar", bot_name: "BarBot")
131
134
 
132
135
  # And now you can call those methods on `BAR_SLACK` to use a different
133
136
  # default channel and name
@@ -138,11 +141,11 @@ BAR_SLACK.message("Message 3", to: "#bar-team-3").post
138
141
 
139
142
  ## CLI Scripts
140
143
 
141
- The gem ships with three executable scripts for sending and managing Slack messages
142
- from the command line. All three accept `-t`/`--slack-token TOKEN` and
144
+ The gem ships with three executable scripts for sending and managing Slack
145
+ messages from the command line. All three accept `-t`/`--slack-token TOKEN` and
143
146
  `-n`/`--bot-name NAME` to override the corresponding environment variables.
144
- Configuration can also come from `SLACK_LINE_SLACK_TOKEN` and friends as described
145
- above.
147
+ Configuration can also come from `SLACK_LINE_SLACK_TOKEN` and friends as
148
+ described above.
146
149
 
147
150
  ### `slack_line_message`
148
151
 
@@ -177,7 +180,8 @@ Options:
177
180
  required with `--update` on a thread)
178
181
  * `-s`/`--save PATH` - write the sent/updated result to PATH as JSON
179
182
  * `-u`/`--look-up-users` - resolve `@mentions` via the Slack API
180
- * `--cache-path PATH` / `--cache-duration DURATION` - disk-cache user/group lookups
183
+ * `--cache-path PATH` / `--cache-duration DURATION` - disk-cache user/group
184
+ lookups
181
185
  * `--no-backoff` - disable per-message sleep delays
182
186
 
183
187
  When no content arguments are given and no DSL is piped, the script reads DSL
@@ -224,8 +228,9 @@ and appends replies along the way. The sent message is persisted to a file;
224
228
  subsequent invocations load and re-persist that file to know which Slack message
225
229
  to update.
226
230
 
227
- Messages are formatted as `[STATE] body`. The `--state` and `--message` flags each
228
- update their respective part independently; omitting one leaves it unchanged on update.
231
+ Messages are formatted as `[STATE] body`. The `--state` and `--message` flags
232
+ each update their respective part independently; omitting one leaves it
233
+ unchanged on update.
229
234
 
230
235
  ```sh
231
236
  # Initial post - creates /tmp/deploy.json and posts "[running] Deploy started"
@@ -247,14 +252,16 @@ slack_line_stateful_thread --path /tmp/deploy.json --thread --message "Step 1 co
247
252
 
248
253
  Options:
249
254
 
250
- * `--path PATH` - (required) file path used to persist the sent message between invocations
251
- * `-p`/`--post-to TARGET` - channel or user; required on the first call, forbidden
252
- thereafter
253
- * `-s`/`--state STATE` - the state label shown in brackets; required on first call
254
- * `-m`/`--message MESSAGE` - the message body; required on first call and when using
255
- `--thread`
256
- * `--thread` - append a reply instead of updating the main message (mutually exclusive
257
- with `--state`)
255
+ * `--path PATH` - (required) file path used to persist the sent message between
256
+ invocations
257
+ * `-p`/`--post-to TARGET` - channel or user; required on the first call,
258
+ forbidden thereafter
259
+ * `-s`/`--state STATE` - the state label shown in brackets; required on first
260
+ call
261
+ * `-m`/`--message MESSAGE` - the message body; required on first call and when
262
+ using `--thread`
263
+ * `--thread` - append a reply instead of updating the main message (mutually
264
+ exclusive with `--state`)
258
265
 
259
266
  ## Slack App Permissions
260
267
 
@@ -262,9 +269,10 @@ In order to post/update messages, the app behind your `SLACK_LINE_TOKEN` can use
262
269
  these permissions:
263
270
 
264
271
  * `chat:write` - send messages at all.
265
- * `chat:write.public` - send messages to public channels your app _isn't a member
266
- of_ (so you don't need to invite them to the relevant channels to make them work).
272
+ * `chat:write.public` - send messages to public channels your app _isn't a
273
+ member of_ (so you don't need to invite them to the relevant channels to make
274
+ them work).
267
275
  * `im:write` - start direct messages with individuals.
268
- * `users:read` and `usergroups:read` - look up users/groups for (a) messaging them
269
- directly or (b) supporting the `look_up_users` config option (for those more
270
- restrictive workspaces)
276
+ * `users:read` and `usergroups:read` - look up users/groups for (a) messaging
277
+ them directly or (b) supporting the `look_up_users` config option (for those
278
+ more restrictive workspaces)
@@ -12,9 +12,9 @@ module SlackLine
12
12
 
13
13
  memoize def slack_client = Slack::Web::Client.new(token: configuration.slack_token)
14
14
 
15
- def message(*text_or_blocks, &dsl_block) = Message.new(*text_or_blocks, client: self, &dsl_block)
15
+ def message(*text_or_blocks, to: nil, &dsl_block) = Message.new(*text_or_blocks, client: self, to:, &dsl_block)
16
16
 
17
- def thread(*messages, &dsl_block) = Thread.new(*messages, client: self, &dsl_block)
17
+ def thread(*messages, to: nil, &dsl_block) = Thread.new(*messages, client: self, to:, &dsl_block)
18
18
 
19
19
  memoize def users = Users.new(client: self)
20
20
 
@@ -3,14 +3,17 @@ module SlackLine
3
3
  extend Forwardable
4
4
  include Memoization
5
5
 
6
- def initialize(*text_or_blocks, client:, &dsl_block)
6
+ def initialize(*text_or_blocks, client:, to: nil, &dsl_block)
7
7
  @text_or_blocks = text_or_blocks
8
8
  @dsl_block = dsl_block
9
9
  @client = client
10
+ @to = to
10
11
 
11
12
  validate!
12
13
  end
13
14
 
15
+ attr_reader :to
16
+
14
17
  memoize def content
15
18
  if @dsl_block
16
19
  MessageContext.new(&@dsl_block).content
@@ -30,7 +33,7 @@ module SlackLine
30
33
  "https://app.slack.com/block-kit-builder##{escaped_json}"
31
34
  end
32
35
 
33
- def post(to: nil, thread_ts: nil) = MessageSender.new(message: self, client:, to:, thread_ts:).post
36
+ def post(to: nil, thread_ts: nil) = MessageSender.new(message: self, client:, to: to || self.to, thread_ts:).post
34
37
 
35
38
  private
36
39
 
@@ -49,7 +52,7 @@ module SlackLine
49
52
 
50
53
  def validate_type!
51
54
  unless @text_or_blocks.empty? || blocks?(@text_or_blocks) || strings?(@text_or_blocks)
52
- raise(ArgumentError, "Invalid content type: #{@text_or_blocks.class}")
55
+ raise(ArgumentError, "Invalid content type: #{@text_or_blocks.map(&:class).uniq.join(", ")}")
53
56
  end
54
57
  end
55
58
 
@@ -12,6 +12,8 @@ module SlackLine
12
12
  attr_reader :content
13
13
 
14
14
  def text(content, plain: false)
15
+ raise(ArgumentError, "A section can only have one text.") if @in_progress_section.text
16
+
15
17
  if plain
16
18
  @in_progress_section.plain_text(text: content)
17
19
  else
@@ -4,14 +4,17 @@ module SlackLine
4
4
  include Enumerable
5
5
  include Memoization
6
6
 
7
- def initialize(*supplied_messages, client:, &dsl_block)
7
+ def initialize(*supplied_messages, client:, to: nil, &dsl_block)
8
8
  @supplied_messages = supplied_messages
9
9
  @dsl_block = dsl_block
10
10
  @client = client
11
+ @to = to
11
12
 
12
13
  validate!
13
14
  end
14
15
 
16
+ attr_reader :to
17
+
15
18
  # an Array of SlackLine::Messages
16
19
  memoize def messages = message_contents.map { |mc| convert_supplied_message(mc) }
17
20
 
@@ -20,11 +23,12 @@ module SlackLine
20
23
  memoize def builder_urls = messages.map(&:builder_url)
21
24
 
22
25
  def post(to: nil)
26
+ target = to || self.to || messages.filter_map(&:to).first
23
27
  sent_messages = []
24
28
  thread_ts = nil
25
29
 
26
30
  messages.each do |message|
27
- sent = message.post(to:, thread_ts:)
31
+ sent = message.post(to: target, thread_ts:)
28
32
  thread_ts ||= sent.ts
29
33
  sent_messages << sent
30
34
  end
@@ -1,3 +1,3 @@
1
1
  module SlackLine
2
- VERSION = "1.2".freeze
2
+ VERSION = "1.4".freeze
3
3
  end
data/slack_line.gemspec CHANGED
@@ -46,4 +46,5 @@ Gem::Specification.new do |spec|
46
46
 
47
47
  spec.add_dependency "slack-ruby-block-kit", "~> 0.23.0"
48
48
  spec.add_dependency "slack-ruby-client", "~> 3.1.0"
49
+ spec.add_dependency "reline", ">= 0.6"
49
50
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slack_line
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.2'
4
+ version: '1.4'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Mueller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-16 00:00:00.000000000 Z
11
+ date: 2026-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: 3.1.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: reline
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0.6'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0.6'
167
181
  description: |
168
182
  Sending messages with the Slack API is not that difficult, but I've had
169
183
  to solve the same problems a lot of times at different companies. This
@@ -189,6 +203,7 @@ files:
189
203
  - ".standard.yml"
190
204
  - CHANGELOG.md
191
205
  - Gemfile
206
+ - LICENSE
192
207
  - README.md
193
208
  - bin/slack_line_message
194
209
  - bin/slack_line_stateful_thread