slack-ruby-block-kit 0.23.0 → 0.25.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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +9 -3
  3. data/.github/workflows/release.yml +7 -19
  4. data/CHANGELOG.md +20 -1
  5. data/Gemfile +5 -2
  6. data/Gemfile.lock +59 -22
  7. data/README.md +10 -7
  8. data/examples/README.md +18 -0
  9. data/examples/comprehensive_rich_text_blocks.rb +121 -0
  10. data/examples/config.rb +19 -0
  11. data/examples/example_helper.rb +22 -0
  12. data/examples/simple_example.rb +33 -0
  13. data/examples/simple_rich_text_blocks.rb +26 -0
  14. data/lib/slack/block_kit/blocks.rb +8 -0
  15. data/lib/slack/block_kit/composition/option_group.rb +2 -2
  16. data/lib/slack/block_kit/element/multi_static_select.rb +2 -1
  17. data/lib/slack/block_kit/element/radio_buttons.rb +2 -1
  18. data/lib/slack/block_kit/element/static_select.rb +2 -1
  19. data/lib/slack/block_kit/element/timepicker.rb +1 -1
  20. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/channel.rb +32 -0
  21. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/emoji.rb +27 -0
  22. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/link.rb +36 -0
  23. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/style_helper.rb +25 -0
  24. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/text.rb +32 -0
  25. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/user.rb +32 -0
  26. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/usergroup.rb +32 -0
  27. data/lib/slack/block_kit/layout/rich_text/rich_text_elements.rb +36 -0
  28. data/lib/slack/block_kit/layout/rich_text/rich_text_list.rb +51 -0
  29. data/lib/slack/block_kit/layout/rich_text/rich_text_preformatted.rb +38 -0
  30. data/lib/slack/block_kit/layout/rich_text/rich_text_quote.rb +38 -0
  31. data/lib/slack/block_kit/layout/rich_text/rich_text_section.rb +36 -0
  32. data/lib/slack/block_kit/layout/rich_text.rb +73 -0
  33. data/lib/slack/block_kit/version.rb +1 -1
  34. metadata +26 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c1823b83c807b7c74ed6dc2a6c9adfd1945de04ab0cc6728d2d0864e0e6ed2e
4
- data.tar.gz: 2b90261eac6e5b840d92b9d6492ef59c7a98558104c95c3b0cd3821fe8a00619
3
+ metadata.gz: 9ab3214e279c311f218493c2d98aa4662d1a121d9c005f6fa0e77909503e66ae
4
+ data.tar.gz: b88b6e9b0aeeb0dd6d245d5abf1d12d8558efe6c9c5b6b4a48ae49ab79e58b09
5
5
  SHA512:
6
- metadata.gz: 41292e69ae30c232a9363259bc393cad93bac9b795a2e1bfc96c378f439072cb60947df3992c1f5a62a551bfa40c140a8f0b65fbfe659497355f524ad105bae0
7
- data.tar.gz: fed6537c6e306897a06b34a676fef07289694c36350e097cbe5f7f45abe2493c92f0175c5d5a7d7f7e6e9b410aa43bb1f0a226f7540de59f3fe37acd8911a208
6
+ metadata.gz: 4bba843df81284b916f1a230e8b46e70c0a61afa1843975f2f01914420621829b37326275a8d358d6451f16f2906375beed0b7b4ca2833029c535d07bf16d6a0
7
+ data.tar.gz: ec3cea5f071e44788cc4ff044c6089c2f15ef7e0b52b1b58a1086f2c6e597adcc354c5935f5c5ddf5b7fc791ca3bdcf4d57a4cd5435a0304259d336590386b68
@@ -8,12 +8,16 @@ on:
8
8
 
9
9
  jobs:
10
10
  build:
11
+ permissions:
12
+ contents: write
13
+ id-token: write
14
+
11
15
  runs-on: ubuntu-latest
12
16
  continue-on-error: ${{ matrix.experimental }}
13
17
  strategy:
14
18
  fail-fast: false
15
19
  matrix:
16
- ruby: [ '2.6', '2.7', '3.0', '3.1' ]
20
+ ruby: [ '2.7', '3.0', '3.1', '3.2', '3.3' ]
17
21
  experimental: [ false ]
18
22
  name: Ruby ${{ matrix.ruby }}
19
23
  steps:
@@ -21,7 +25,9 @@ jobs:
21
25
  - uses: ruby/setup-ruby@v1
22
26
  with:
23
27
  ruby-version: ${{ matrix.ruby }}
24
- - run: gem install bundler:2.1.4
25
- - run: bundle install
28
+ bundler-cache: true
29
+ - uses: codecov/codecov-action@v4
30
+ with:
31
+ use_oidc: true
26
32
  - run: bundle exec rspec --format progress
27
33
  - run: bundle exec rubocop
@@ -2,30 +2,18 @@ name: Release
2
2
 
3
3
  on:
4
4
  workflow_dispatch:
5
- inputs:
6
- otp:
7
- name: 'RubyGems OTP Code'
8
- required: true
9
-
10
5
  jobs:
11
6
  release:
7
+ permissions:
8
+ contents: write
9
+ id-token: write
10
+
12
11
  name: Release
13
12
  runs-on: ubuntu-latest
14
13
  steps:
15
14
  - uses: actions/checkout@v2
16
15
  - uses: ruby/setup-ruby@v1
17
16
  with:
18
- ruby-version: 2.7
19
- - name: Mask OTP
20
- run: |
21
- OTP=$(jq -r '.inputs.otp' $GITHUB_EVENT_PATH)
22
- echo "::add-mask::$OTP"
23
- - run: gem update --system
24
- - run: git config --global user.email github-action@users.noreply.github.com
25
- - run: git config --global user.name GitHub Actions
26
- - run: git config --global user.password ${{ github.token }}
27
- - run: bundle install
28
- - run: bundle exec rake release
29
- env:
30
- GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
31
- GEM_HOST_OTP_CODE: ${{ github.event.inputs.otp }}
17
+ ruby-version: 3.3
18
+ bundler-cache: true
19
+ - uses: rubygems/release-gem@v1
data/CHANGELOG.md CHANGED
@@ -25,6 +25,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
25
25
  ### Security
26
26
  - N/A
27
27
 
28
+ ## [0.25.0] - 2024-11-22
29
+
30
+ ### Added
31
+ - Allow setting `description:` to `StaticSelect`, `MultiStaticSelect`, `RadioButtons`, & any `OptionGroup`s. (#195 by @resputin)
32
+
33
+
34
+ ## [0.24.0] - 2024-04-07
35
+
36
+ ### Added
37
+
38
+ - Added support for Rich Text Block via `Slack::BlockKit::Layout::RichText` (#185 by @GetOutOfMyBakery)
39
+
40
+
41
+ ### Changed
42
+ - Codecov reporting via GitHub Actions OIDC (#188 by @CGA1123)
43
+ - Rubygems releasing via GitHub Actions OIDC (#188 by @CGA1123)
28
44
 
29
45
  ## [0.23.0] - 2023-08-07
30
46
 
@@ -181,7 +197,10 @@ This release contains a breaking change on the `Layout::Actions` interface.
181
197
  - Fixed initial options in multi select blocks (#46 by @caalberts)
182
198
 
183
199
 
184
- [Unreleased]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.22.0...HEAD
200
+ [Unreleased]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.25.0...HEAD
201
+ [0.25.0]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.24.0...v0.25.0
202
+ [0.24.0]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.23.0...v0.24.0
203
+ [0.23.0]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.22.0...v0.23.0
185
204
  [0.22.0]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.21.0...v0.22.0
186
205
  [0.21.0]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.20.0...v0.21.0
187
206
  [0.20.0]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.19.0...v0.20.0
data/Gemfile CHANGED
@@ -7,12 +7,15 @@ gemspec
7
7
  gem 'dotenv', '~> 2'
8
8
  gem 'faraday', '~> 1'
9
9
  gem 'pry', '~> 0.14'
10
+ gem 'racc'
10
11
  gem 'rake', '~> 13'
11
12
  gem 'rspec', '~> 3'
12
13
  gem 'rspec_junit_formatter', '~> 0.6'
13
14
 
14
- gem 'codecov', '~> 0.6', require: false
15
+ gem 'debug', '~> 1.9', require: false
16
+ gem 'retest', '~> 1.13', require: false
15
17
  gem 'rubocop', '~> 1', require: false
16
18
  gem 'rubocop-rake', '~> 0.6', require: false
17
19
  gem 'rubocop-rspec', '~> 2', require: false
18
- gem 'simplecov', '~> 0.21', require: false
20
+ gem 'simplecov', '~> 0.22', require: false
21
+ gem 'simplecov-cobertura', require: false
data/Gemfile.lock CHANGED
@@ -1,17 +1,18 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- slack-ruby-block-kit (0.23.0)
4
+ slack-ruby-block-kit (0.25.0)
5
5
  zeitwerk (~> 2.6)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  ast (2.4.2)
11
- codecov (0.6.0)
12
- simplecov (>= 0.15, < 0.22)
13
11
  coderay (1.1.3)
14
- diff-lcs (1.5.0)
12
+ debug (1.9.1)
13
+ irb (~> 1.10)
14
+ reline (>= 0.3.8)
15
+ diff-lcs (1.5.1)
15
16
  docile (1.4.0)
16
17
  dotenv (2.8.1)
17
18
  faraday (1.10.3)
@@ -37,31 +38,56 @@ GEM
37
38
  faraday-patron (1.0.0)
38
39
  faraday-rack (1.0.0)
39
40
  faraday-retry (1.0.3)
41
+ ffi (1.16.3)
42
+ io-console (0.7.2)
43
+ irb (1.12.0)
44
+ rdoc
45
+ reline (>= 0.4.2)
46
+ listen (3.9.0)
47
+ rb-fsevent (~> 0.10, >= 0.10.3)
48
+ rb-inotify (~> 0.9, >= 0.9.10)
40
49
  method_source (1.0.0)
41
50
  multipart-post (2.3.0)
51
+ observer (0.1.2)
42
52
  parallel (1.22.1)
43
53
  parser (3.1.2.0)
44
54
  ast (~> 2.4.1)
45
55
  pry (0.14.2)
46
56
  coderay (~> 1.1)
47
57
  method_source (~> 1.0)
58
+ psych (5.1.2)
59
+ stringio
60
+ racc (1.8.0)
48
61
  rainbow (3.1.1)
49
- rake (13.0.6)
62
+ rake (13.2.1)
63
+ rb-fsevent (0.11.2)
64
+ rb-inotify (0.10.1)
65
+ ffi (~> 1.0)
66
+ rdoc (6.6.3.1)
67
+ psych (>= 4.0.0)
50
68
  regexp_parser (2.3.1)
51
- rexml (3.2.5)
52
- rspec (3.12.0)
53
- rspec-core (~> 3.12.0)
54
- rspec-expectations (~> 3.12.0)
55
- rspec-mocks (~> 3.12.0)
56
- rspec-core (3.12.2)
57
- rspec-support (~> 3.12.0)
58
- rspec-expectations (3.12.3)
69
+ reline (0.4.3)
70
+ io-console (~> 0.5)
71
+ retest (1.13.2)
72
+ listen (~> 3.9)
73
+ observer (~> 0.1)
74
+ string-similarity (~> 2.1)
75
+ tty-option (~> 0.1)
76
+ rexml (3.2.8)
77
+ strscan (>= 3.0.9)
78
+ rspec (3.13.0)
79
+ rspec-core (~> 3.13.0)
80
+ rspec-expectations (~> 3.13.0)
81
+ rspec-mocks (~> 3.13.0)
82
+ rspec-core (3.13.0)
83
+ rspec-support (~> 3.13.0)
84
+ rspec-expectations (3.13.0)
59
85
  diff-lcs (>= 1.2.0, < 2.0)
60
- rspec-support (~> 3.12.0)
61
- rspec-mocks (3.12.6)
86
+ rspec-support (~> 3.13.0)
87
+ rspec-mocks (3.13.0)
62
88
  diff-lcs (>= 1.2.0, < 2.0)
63
- rspec-support (~> 3.12.0)
64
- rspec-support (3.12.1)
89
+ rspec-support (~> 3.13.0)
90
+ rspec-support (3.13.0)
65
91
  rspec_junit_formatter (0.6.0)
66
92
  rspec-core (>= 2, < 4, != 2.12.0)
67
93
  rubocop (1.28.2)
@@ -81,32 +107,43 @@ GEM
81
107
  rubocop (~> 1.19)
82
108
  ruby-progressbar (1.11.0)
83
109
  ruby2_keywords (0.0.5)
84
- simplecov (0.21.2)
110
+ simplecov (0.22.0)
85
111
  docile (~> 1.1)
86
112
  simplecov-html (~> 0.11)
87
113
  simplecov_json_formatter (~> 0.1)
114
+ simplecov-cobertura (2.1.0)
115
+ rexml
116
+ simplecov (~> 0.19)
88
117
  simplecov-html (0.12.3)
89
- simplecov_json_formatter (0.1.3)
118
+ simplecov_json_formatter (0.1.4)
119
+ string-similarity (2.1.0)
120
+ stringio (3.1.0)
121
+ strscan (3.1.0)
122
+ tty-option (0.3.0)
90
123
  unicode-display_width (2.1.0)
91
- zeitwerk (2.6.11)
124
+ zeitwerk (2.6.18)
92
125
 
93
126
  PLATFORMS
94
127
  ruby
95
128
  x86_64-darwin-19
129
+ x86_64-darwin-23
96
130
  x86_64-linux
97
131
 
98
132
  DEPENDENCIES
99
- codecov (~> 0.6)
133
+ debug (~> 1.9)
100
134
  dotenv (~> 2)
101
135
  faraday (~> 1)
102
136
  pry (~> 0.14)
137
+ racc
103
138
  rake (~> 13)
139
+ retest (~> 1.13)
104
140
  rspec (~> 3)
105
141
  rspec_junit_formatter (~> 0.6)
106
142
  rubocop (~> 1)
107
143
  rubocop-rake (~> 0.6)
108
144
  rubocop-rspec (~> 2)
109
- simplecov (~> 0.21)
145
+ simplecov (~> 0.22)
146
+ simplecov-cobertura
110
147
  slack-ruby-block-kit!
111
148
 
112
149
  BUNDLED WITH
data/README.md CHANGED
@@ -67,8 +67,8 @@ blocks = Slack::BlockKit.blocks do |b|
67
67
  b.append(a_prebuilt_block)
68
68
  end
69
69
 
70
+ body = { blocks: blocks.as_json }
70
71
  webhook_url = 'https://hooks.slack.com/services/your/webhook/url'
71
- body = { blocks: blocks.as_json, text: 'New block message!' }
72
72
 
73
73
  response = Faraday.post(
74
74
  webhook_url,
@@ -81,8 +81,10 @@ This will create a message like this:
81
81
 
82
82
  ![example block message](https://git.io/fjDWR)
83
83
 
84
- You can also check out the [`slackerduty`](https://github.com/CGA1123/slackerduty) project for some example,
85
- [`Slackerduty::Alert`](https://github.com/CGA1123/slackerduty/blob/b33d708124ddf36d1432080ba7e16e66fefa6993/lib/slackerduty/alert.rb#L28-L34) and [`Slackerduty::Blocks`](https://github.com/CGA1123/slackerduty/blob/master/lib/slackerduty/blocks) may be helpful places to start.
84
+ See [`./examples`](./examples/), and [`./examples/README.md`](./examples/README.md), for more worked examples and guidance.
85
+
86
+ You can also check out the [`slackerduty`](https://github.com/CGA1123/slackerduty) project for some more examples,
87
+ [`Slackerduty::Alert`](https://github.com/CGA1123/slackerduty/blob/b33d708124ddf36d1432080ba7e16e66fefa6993/lib/slackerduty/alert.rb#L28-L34) and [`Slackerduty::Blocks`](https://github.com/CGA1123/slackerduty/blob/¦master/lib/slackerduty/blocks) may be helpful places to start.
86
88
 
87
89
  ## Contributing
88
90
 
@@ -96,12 +98,13 @@ The gem is available as open source under the terms of the [MIT License](https:/
96
98
 
97
99
  ## Releasing
98
100
 
99
- Releasing is automated via the `.github/workflows/release.yml` which allows for
100
- an OTP code to be passed in to authorize the release with MFA. If GitHub
101
- Actions is running slow it might take another attempt to make sure the OTP code
102
- is still valid when the workflow tries to push.
101
+ Releasing is automated via the `.github/workflows/release.yml` which runs via
102
+ [Trusted Publishing] authenticating with RubyGems via GitHub Action's OIDC
103
+ integration.
103
104
 
104
105
  - Update `CHANGELOG` for the latest version (remember to update the comparison links + add in an `Unreleased` section again)
105
106
  - Update `lib/slack/block_kit/version.rb` and run `bundle` to update the `Gemfile.lock`
106
107
  - Push that!
107
108
  - Run the `Release` workflow
109
+
110
+ [Trusted Publishing]: https://guides.rubygems.org/trusted-publishing/
@@ -0,0 +1,18 @@
1
+ # Examples
2
+
3
+ These example files demonstrate worked examples of how to use the gem.
4
+ They are written in a way that you can:
5
+ - send the messages to your own Slack workspace, when a valid Slack `webhook_url` has been provided (see `./config.rb`)
6
+ - copy and paste the output to Slack's [Block Builder Kit](https://app.slack.com/block-kit-builder) to validate the output without having to send a message to Slack
7
+
8
+ > [!NOTE]
9
+ > There are some values that need to be valid otherwise Slack, or the Block Builder Kit UI, will return a warning reporting the block output is invalid
10
+
11
+ ## How to use
12
+ 1. Update `./config.rb`
13
+ 1. Run `bundle exec examples/simple_example.rb`
14
+
15
+ > [!TIP]
16
+ > When using [Block Builder Kit](https://app.slack.com/block-kit-builder) to validate the output, set `SUPPRESS_WEBHOOK_MESSAGE=true` to suppress lines that would invalid the output, e.g.:
17
+ > `SUPPRESS_WEBHOOK_MESSAGE=true examples/simple_example.rb | pbcopy` # on Mac
18
+ > `SUPPRESS_WEBHOOK_MESSAGE=true examples/simple_example.rb | xclip -selection clipboard` # on Linux
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/slack-ruby-block-kit'
5
+ require_relative './config'
6
+ require_relative './example_helper'
7
+ require 'json'
8
+
9
+ # rubocop:disable Metrics/BlockLength
10
+ blocks = Slack::BlockKit.blocks do |b|
11
+ b.rich_text do |rt|
12
+ rt.rich_text_section do |rts|
13
+ rts.text(text: "Bold text\n", styles: ['bold'])
14
+ rts.text(text: "Italic text\n", styles: ['italic'])
15
+ rts.text(text: "strikethrough text\n", styles: ['strike'])
16
+ rts.text(text: "This is a code block!\n", styles: ['code'])
17
+ rts.text(
18
+ text: "This text has multiple styling\n",
19
+ styles: %w[
20
+ bold
21
+ italic
22
+ strike
23
+ ]
24
+ )
25
+ end
26
+ end
27
+
28
+ b.divider
29
+
30
+ b.rich_text do |rt|
31
+ rt.rich_text_section do |rts|
32
+ rts.text(text: 'Tagging a user:')
33
+ rts.user(user_id: Config.user_id)
34
+ rts.text(text: "\nTagging a user with some styling:")
35
+ rts.user(user_id: Config.user_id, styles: %w[bold italic])
36
+ rts.text(text: "\n")
37
+ end
38
+ end
39
+
40
+ b.divider
41
+
42
+ b.rich_text do |rt|
43
+ rt.rich_text_section do |rts|
44
+ rts.text(text: 'Tagging a user group:')
45
+ rts.usergroup(usergroup_id: Config.usergroup_id)
46
+ rts.text(text: "\nTagging a user group with some styling:")
47
+ rts.usergroup(usergroup_id: Config.usergroup_id, styles: ['bold'])
48
+ rts.text(text: "\n")
49
+ end
50
+ end
51
+
52
+ b.divider
53
+
54
+ b.rich_text do |rt|
55
+ rt.rich_text_section do |rts|
56
+ rts.text(text: 'Channel tag: ')
57
+ rts.channel(channel_id: Config.channel_id)
58
+ rts.text(text: "\n")
59
+ end
60
+
61
+ rt.rich_text_section do |rts|
62
+ rts.text(text: 'Link to a great repo: ')
63
+ rts.emoji(name: 'point_right')
64
+ rts.link(url: 'https://github.com/CGA1123/slack-ruby-block-kit')
65
+ rts.emoji(name: 'point_left')
66
+ rts.text(text: "\n")
67
+ end
68
+
69
+ rt.rich_text_section do |rts|
70
+ rts.emoji(name: 'muscle')
71
+ rts.link(
72
+ url: 'https://github.com/CGA1123/slack-ruby-block-kit',
73
+ text: 'Link with alternative title',
74
+ unsafe: true,
75
+ styles: %w[
76
+ bold
77
+ italic
78
+ ]
79
+ )
80
+ rts.emoji(name: 'muscle-two')
81
+ rts.text(text: "\n")
82
+ end
83
+ end
84
+
85
+ b.divider
86
+
87
+ b.rich_text do |rt|
88
+ rt.rich_text_list(style: 'bullet', indent: 1, offset: 1, border: 1) do |rtl|
89
+ rtl.rich_text_section do |rts|
90
+ rts.text(text: "Rich text\n", styles: %w[bold italic strike])
91
+ rts.text(text: "strikethrough text\n", styles: ['strike'])
92
+ end
93
+
94
+ rtl.rich_text_section do |rts|
95
+ rts.text(text: "strikethrough text\n", styles: ['strike'])
96
+ rts.text(text: "code block text\n", styles: ['code'])
97
+ end
98
+ end
99
+
100
+ rt.rich_text_list(style: 'ordered', indent: 2, offset: 2, border: 1) do |rtl|
101
+ rtl.rich_text_section do |rts|
102
+ rts.text(text: "Some text\n", styles: ['bold'])
103
+ rts.text(text: "Some more text\n", styles: ['strike'])
104
+ end
105
+ end
106
+
107
+ rt.rich_text_preformatted(border: 1) do |rtp|
108
+ rtp.text(text: 'Some text', styles: %w[bold italic])
109
+ end
110
+
111
+ rt.rich_text_quote(border: 1) do |rtq|
112
+ rtq.text(text: 'Some more text', styles: %w[bold strike])
113
+ end
114
+ end
115
+ end
116
+ # rubocop:enable Metrics/BlockLength
117
+
118
+ body = { blocks: blocks.as_json }
119
+ puts JSON.pretty_generate(body)
120
+
121
+ ExampleHelper.post_to_slack(body)
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # When using Slack's Block Builder Kit, https://app.slack.com/block-kit-builder, there are some values that need
4
+ # to be valid otherwise the UI will return a warning and report the block as being invalid.
5
+
6
+ # Store and populate any other examples here, and use throughout 'examples/' scripts.
7
+
8
+ module Config
9
+ class << self
10
+ attr_accessor :channel_id, :user_id, :usergroup_id, :webhook_url
11
+ end
12
+
13
+ self.channel_id = 'CL9QH354H'
14
+ self.user_id = 'URLQ55EMB'
15
+ self.usergroup_id = 'SBR3Q0B2T'
16
+
17
+ # Uncomment and provide a valid webook to post to `examples/` scripts to Slack:
18
+ # self.webhook_url = 'https://hooks.slack.com/services/your/webhook/url'
19
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+
5
+ module ExampleHelper
6
+ def self.print_output(line)
7
+ warn line unless ENV.fetch('SUPPRESS_WEBHOOK_MESSAGE', nil) == 'true'
8
+ end
9
+
10
+ def self.post_to_slack(body)
11
+ if Config.webhook_url
12
+ print_output 'Posting to Slack ...'
13
+ Faraday.post(
14
+ Config.webhook_url,
15
+ body.to_json,
16
+ 'Content-Type' => 'application/json'
17
+ )
18
+ else
19
+ print_output 'Set a "webhook_url" in "./config.rb" in order to test sending this message to Slack.'
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/slack-ruby-block-kit'
5
+ require_relative './config'
6
+ require_relative './example_helper'
7
+ require 'json'
8
+
9
+ a_prebuilt_block = Slack::BlockKit::Layout::Section.new
10
+ text = Slack::BlockKit::Composition::Mrkdwn.new(text: ':wave: *hello*')
11
+ an_image = Slack::BlockKit::Element::Image.new(image_url: 'https://git.io/fjDW8', alt_text: 'a picture')
12
+ a_prebuilt_block.accessorise(an_image)
13
+ a_prebuilt_block.text = text
14
+
15
+ blocks = Slack::BlockKit.blocks do |b|
16
+ b.section do |s|
17
+ s.plain_text(text: 'Some plain text message!')
18
+ s.button(text: 'A button that is important', style: 'primary', action_id: 'id')
19
+ end
20
+
21
+ b.divider
22
+
23
+ b.context do |c|
24
+ c.mrkdwn(text: '_some italicised text for context_')
25
+ end
26
+
27
+ b.append(a_prebuilt_block)
28
+ end
29
+
30
+ body = { blocks: blocks.as_json }
31
+ puts JSON.pretty_generate(body)
32
+
33
+ ExampleHelper.post_to_slack(body)
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/slack-ruby-block-kit'
5
+ require_relative './config'
6
+ require_relative './example_helper'
7
+ require 'json'
8
+
9
+ a_prebuilt_block = Slack::BlockKit::Layout::RichText.new
10
+ bold_rich_text_section = Slack::BlockKit::Layout::RichText::RichTextSection.new.text(text: 'Bold text', styles: ['bold'])
11
+ a_prebuilt_block.append(bold_rich_text_section)
12
+
13
+ italic_rich_text_section = Slack::BlockKit::Layout::RichText::RichTextSection.new.text(text: 'Italic text', styles: ['italic'])
14
+ a_prebuilt_block.append(italic_rich_text_section)
15
+
16
+ channel_rich_text = Slack::BlockKit::Layout::RichText::RichTextSection.new.channel(channel_id: Config.channel_id, styles: %w[bold italic])
17
+ a_prebuilt_block.append(channel_rich_text)
18
+
19
+ blocks = Slack::BlockKit.blocks do |b|
20
+ b.append(a_prebuilt_block)
21
+ end
22
+
23
+ body = { blocks: blocks.as_json }
24
+ puts JSON.pretty_generate(body)
25
+
26
+ ExampleHelper.post_to_slack(body)
@@ -55,6 +55,14 @@ module Slack
55
55
  append(block)
56
56
  end
57
57
 
58
+ def rich_text(block_id: nil)
59
+ block = Layout::RichText.new(block_id: block_id)
60
+
61
+ yield(block) if block_given?
62
+
63
+ append(block)
64
+ end
65
+
58
66
  def video(alt_text:, thumbnail_url:, video_url:, title:, description:, **optional_args)
59
67
  block = Layout::Video.new(
60
68
  alt_text: alt_text,
@@ -17,8 +17,8 @@ module Slack
17
17
  yield(self) if block_given?
18
18
  end
19
19
 
20
- def option(text:, value:, emoji: nil, initial: false)
21
- @options << Option.new(text: text, value: value, emoji: emoji, initial: initial)
20
+ def option(text:, value:, description: nil, emoji: nil, initial: false)
21
+ @options << Option.new(text: text, value: value, description: description, emoji: emoji, initial: initial)
22
22
 
23
23
  self
24
24
  end
@@ -37,11 +37,12 @@ module Slack
37
37
  yield(self) if block_given?
38
38
  end
39
39
 
40
- def option(value:, text:, initial: false, emoji: nil)
40
+ def option(value:, text:, description: nil, initial: false, emoji: nil)
41
41
  @options ||= []
42
42
  @options << Composition::Option.new(
43
43
  value: value,
44
44
  text: text,
45
+ description: description,
45
46
  emoji: emoji,
46
47
  initial: initial
47
48
  )
@@ -21,10 +21,11 @@ module Slack
21
21
  yield(self) if block_given?
22
22
  end
23
23
 
24
- def option(value:, text:, initial: false, emoji: nil)
24
+ def option(value:, text:, description: nil, initial: false, emoji: nil)
25
25
  option = Composition::Option.new(
26
26
  value: value,
27
27
  text: text,
28
+ description: description,
28
29
  initial: initial,
29
30
  emoji: emoji
30
31
  )
@@ -27,11 +27,12 @@ module Slack
27
27
  yield(self) if block_given?
28
28
  end
29
29
 
30
- def option(value:, text:, initial: false, emoji: nil)
30
+ def option(value:, text:, description: nil, initial: false, emoji: nil)
31
31
  @options ||= []
32
32
  @options << Composition::Option.new(
33
33
  value: value,
34
34
  text: text,
35
+ description: description,
35
36
  emoji: emoji,
36
37
  initial: initial
37
38
  )
@@ -16,7 +16,7 @@ module Slack
16
16
  TYPE = 'timepicker'
17
17
 
18
18
  def initialize(action_id:, placeholder: nil, initial: nil, emoji: nil, focus_on_load: nil)
19
- @placeholder = placeholder_text(placeholder, emoji) if placeholder
19
+ @placeholder = placeholder_text(placeholder, emoji)
20
20
  @initial_time = initial
21
21
  @action_id = action_id
22
22
  @focus_on_load = focus_on_load
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ module RichTextElements
8
+ # https://api.slack.com/reference/block-kit/blocks#element-types
9
+ class Channel
10
+ include RichTextElements::StyleHelper
11
+ TYPE = 'channel'
12
+ VALID_STYLES = %w[bold italic strike highlight client_highlight unlink].freeze
13
+
14
+ def initialize(channel_id:, styles: [])
15
+ @channel_id = channel_id
16
+ @styles = styles
17
+ validate_styles(styles, VALID_STYLES)
18
+ end
19
+
20
+ def as_json(*)
21
+ {
22
+ type: TYPE,
23
+ channel_id: @channel_id,
24
+ style: styles_as_json(@styles)
25
+ }.compact
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ module RichTextElements
8
+ # https://api.slack.com/reference/block-kit/blocks#element-types
9
+ class Emoji
10
+ TYPE = 'emoji'
11
+
12
+ def initialize(name:)
13
+ @name = name
14
+ end
15
+
16
+ def as_json(*)
17
+ {
18
+ type: TYPE,
19
+ name: @name
20
+ }.compact
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ module RichTextElements
8
+ # https://api.slack.com/reference/block-kit/blocks#element-types
9
+ class Link
10
+ include RichTextElements::StyleHelper
11
+ TYPE = 'link'
12
+ VALID_STYLES = %w[bold italic strike code].freeze
13
+
14
+ def initialize(url:, text: nil, unsafe: nil, styles: [])
15
+ @url = url
16
+ @text = text
17
+ @unsafe = unsafe
18
+ @styles = styles
19
+ validate_styles(styles, VALID_STYLES)
20
+ end
21
+
22
+ def as_json(*)
23
+ {
24
+ type: TYPE,
25
+ url: @url,
26
+ text: @text,
27
+ unsafe: @unsafe,
28
+ style: styles_as_json(@styles)
29
+ }.compact
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ module RichTextElements
8
+ module StyleHelper
9
+ def validate_styles(provided_styles, valid_styles)
10
+ provided_styles.each do |style|
11
+ raise ArgumentError, "Invalid style: #{style}. Valid styles: #{valid_styles}." unless valid_styles.include?(style)
12
+ end
13
+ end
14
+
15
+ def styles_as_json(styles)
16
+ return if styles.empty?
17
+
18
+ styles.each_with_object({}) { |style, block| block[style] = true }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ module RichTextElements
8
+ # https://api.slack.com/reference/block-kit/blocks#element-types
9
+ class Text
10
+ include RichTextElements::StyleHelper
11
+ TYPE = 'text'
12
+ VALID_STYLES = %w[bold italic strike code].freeze
13
+
14
+ def initialize(text:, styles: [])
15
+ @text = text
16
+ @styles = styles
17
+ validate_styles(styles, VALID_STYLES)
18
+ end
19
+
20
+ def as_json(*)
21
+ {
22
+ type: TYPE,
23
+ text: @text,
24
+ style: styles_as_json(@styles)
25
+ }.compact
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ module RichTextElements
8
+ # https://api.slack.com/reference/block-kit/blocks#element-types
9
+ class User
10
+ include RichTextElements::StyleHelper
11
+ TYPE = 'user'
12
+ VALID_STYLES = %w[bold italic strike highlight client_highlight unlink].freeze
13
+
14
+ def initialize(user_id:, styles: [])
15
+ @user_id = user_id
16
+ @styles = styles
17
+ validate_styles(styles, VALID_STYLES)
18
+ end
19
+
20
+ def as_json(*)
21
+ {
22
+ type: TYPE,
23
+ user_id: @user_id,
24
+ style: styles_as_json(@styles)
25
+ }.compact
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ module RichTextElements
8
+ # https://api.slack.com/reference/block-kit/blocks#element-types
9
+ class Usergroup
10
+ include RichTextElements::StyleHelper
11
+ TYPE = 'usergroup'
12
+ VALID_STYLES = %w[bold italic strike highlight client_highlight unlink].freeze
13
+
14
+ def initialize(usergroup_id:, styles: [])
15
+ @usergroup_id = usergroup_id
16
+ @styles = styles
17
+ validate_styles(styles, VALID_STYLES)
18
+ end
19
+
20
+ def as_json(*)
21
+ {
22
+ type: TYPE,
23
+ usergroup_id: @usergroup_id,
24
+ style: styles_as_json(@styles)
25
+ }.compact
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ module RichTextElements
8
+ # https://api.slack.com/reference/block-kit/blocks#element-types
9
+ def channel(channel_id:, styles: [])
10
+ append(RichTextElements::Channel.new(channel_id: channel_id, styles: styles))
11
+ end
12
+
13
+ def emoji(name:)
14
+ append(RichTextElements::Emoji.new(name: name))
15
+ end
16
+
17
+ def link(url:, text: nil, unsafe: nil, styles: [])
18
+ append(RichTextElements::Link.new(url: url, text: text, unsafe: unsafe, styles: styles))
19
+ end
20
+
21
+ def text(text:, styles: [])
22
+ append(RichTextElements::Text.new(text: text, styles: styles))
23
+ end
24
+
25
+ def user(user_id:, styles: [])
26
+ append(RichTextElements::User.new(user_id: user_id, styles: styles))
27
+ end
28
+
29
+ def usergroup(usergroup_id:, styles: [])
30
+ append(RichTextElements::Usergroup.new(usergroup_id: usergroup_id, styles: styles))
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ # https://api.slack.com/reference/block-kit/blocks#rich_text_list
8
+ class RichTextList
9
+ TYPE = 'rich_text_list'
10
+
11
+ attr_accessor :style, :elements, :indent, :offset, :border
12
+
13
+ def initialize(style:, indent: nil, offset: nil, border: nil)
14
+ @elements = []
15
+ @style = style
16
+ @indent = indent
17
+ @offset = offset
18
+ @border = border
19
+
20
+ yield(self) if block_given?
21
+ end
22
+
23
+ def rich_text_section
24
+ element = RichTextSection.new
25
+
26
+ yield(element) if block_given?
27
+
28
+ append(element)
29
+ end
30
+
31
+ def append(element)
32
+ @elements << element
33
+
34
+ self
35
+ end
36
+
37
+ def as_json(*)
38
+ {
39
+ type: TYPE,
40
+ style: @style,
41
+ elements: @elements.map(&:as_json),
42
+ indent: @indent,
43
+ offset: @offset,
44
+ border: @border
45
+ }.compact
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ # https://api.slack.com/reference/block-kit/blocks#rich_text_preformatted
8
+ class RichTextPreformatted
9
+ include RichTextElements
10
+ TYPE = 'rich_text_preformatted'
11
+
12
+ attr_accessor :elements, :border
13
+
14
+ def initialize(border: nil)
15
+ @elements = []
16
+ @border = border
17
+
18
+ yield(self) if block_given?
19
+ end
20
+
21
+ def append(element)
22
+ @elements << element
23
+
24
+ self
25
+ end
26
+
27
+ def as_json(*)
28
+ {
29
+ type: TYPE,
30
+ border: @border,
31
+ elements: @elements.map(&:as_json)
32
+ }.compact
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ # https://api.slack.com/reference/block-kit/blocks#rich_text_quote
8
+ class RichTextQuote
9
+ include RichTextElements
10
+ TYPE = 'rich_text_quote'
11
+
12
+ attr_accessor :elements, :border
13
+
14
+ def initialize(border: nil)
15
+ @elements = []
16
+ @border = border
17
+
18
+ yield(self) if block_given?
19
+ end
20
+
21
+ def append(element)
22
+ @elements << element
23
+
24
+ self
25
+ end
26
+
27
+ def as_json(*)
28
+ {
29
+ type: TYPE,
30
+ border: @border,
31
+ elements: @elements.map(&:as_json)
32
+ }.compact
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ class RichText
7
+ # https://api.slack.com/reference/block-kit/blocks#rich_text_section
8
+ class RichTextSection
9
+ include RichTextElements
10
+ TYPE = 'rich_text_section'
11
+
12
+ attr_accessor :elements
13
+
14
+ def initialize
15
+ @elements = []
16
+
17
+ yield(self) if block_given?
18
+ end
19
+
20
+ def append(element)
21
+ @elements << element
22
+
23
+ self
24
+ end
25
+
26
+ def as_json(*)
27
+ {
28
+ type: TYPE,
29
+ elements: @elements.map(&:as_json)
30
+ }.compact
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ # Displays formatted, structured representation of text.
7
+ #
8
+ # It is also the output of the Slack client's WYSIWYG message composer, so all messages sent by end-users will have this
9
+ # format. Use this block to include user-defined formatted text in your Block Kit payload. While it is possible to format
10
+ # text with mrkdwn, rich_text is strongly preferred and allows greater flexibility.
11
+ #
12
+ # https://api.slack.com/reference/block-kit/blocks#rich_text
13
+ class RichText
14
+ TYPE = 'rich_text'
15
+
16
+ attr_accessor :elements
17
+
18
+ def initialize(block_id: nil)
19
+ @block_id = block_id
20
+ @elements = []
21
+
22
+ yield(self) if block_given?
23
+ end
24
+
25
+ def rich_text_section
26
+ element = RichTextSection.new
27
+
28
+ yield(element) if block_given?
29
+
30
+ append(element)
31
+ end
32
+
33
+ def rich_text_list(style: 'bullet', indent: nil, offset: nil, border: nil)
34
+ element = RichTextList.new(style: style, indent: indent, offset: offset, border: border)
35
+
36
+ yield(element) if block_given?
37
+
38
+ append(element)
39
+ end
40
+
41
+ def rich_text_preformatted(border: nil)
42
+ element = RichTextPreformatted.new(border: border)
43
+
44
+ yield(element) if block_given?
45
+
46
+ append(element)
47
+ end
48
+
49
+ def rich_text_quote(border: nil)
50
+ element = RichTextQuote.new(border: border)
51
+
52
+ yield(element) if block_given?
53
+
54
+ append(element)
55
+ end
56
+
57
+ def append(element)
58
+ @elements << element
59
+
60
+ self
61
+ end
62
+
63
+ def as_json(*)
64
+ {
65
+ type: TYPE,
66
+ elements: @elements.map(&:as_json),
67
+ block_id: @block_id
68
+ }.compact
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Slack
4
4
  module BlockKit
5
- VERSION = '0.23.0'
5
+ VERSION = '0.25.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slack-ruby-block-kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.0
4
+ version: 0.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Gregg
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-07 00:00:00.000000000 Z
11
+ date: 2024-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -24,7 +24,7 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.6'
27
- description:
27
+ description:
28
28
  email:
29
29
  - c_arlt@hotmail.com
30
30
  executables: []
@@ -46,6 +46,12 @@ files:
46
46
  - LICENSE.txt
47
47
  - README.md
48
48
  - Rakefile
49
+ - examples/README.md
50
+ - examples/comprehensive_rich_text_blocks.rb
51
+ - examples/config.rb
52
+ - examples/example_helper.rb
53
+ - examples/simple_example.rb
54
+ - examples/simple_rich_text_blocks.rb
49
55
  - lib/slack-ruby-block-kit.rb
50
56
  - lib/slack/block_kit.rb
51
57
  - lib/slack/block_kit/blocks.rb
@@ -85,6 +91,19 @@ files:
85
91
  - lib/slack/block_kit/layout/header.rb
86
92
  - lib/slack/block_kit/layout/image.rb
87
93
  - lib/slack/block_kit/layout/input.rb
94
+ - lib/slack/block_kit/layout/rich_text.rb
95
+ - lib/slack/block_kit/layout/rich_text/rich_text_elements.rb
96
+ - lib/slack/block_kit/layout/rich_text/rich_text_elements/channel.rb
97
+ - lib/slack/block_kit/layout/rich_text/rich_text_elements/emoji.rb
98
+ - lib/slack/block_kit/layout/rich_text/rich_text_elements/link.rb
99
+ - lib/slack/block_kit/layout/rich_text/rich_text_elements/style_helper.rb
100
+ - lib/slack/block_kit/layout/rich_text/rich_text_elements/text.rb
101
+ - lib/slack/block_kit/layout/rich_text/rich_text_elements/user.rb
102
+ - lib/slack/block_kit/layout/rich_text/rich_text_elements/usergroup.rb
103
+ - lib/slack/block_kit/layout/rich_text/rich_text_list.rb
104
+ - lib/slack/block_kit/layout/rich_text/rich_text_preformatted.rb
105
+ - lib/slack/block_kit/layout/rich_text/rich_text_quote.rb
106
+ - lib/slack/block_kit/layout/rich_text/rich_text_section.rb
88
107
  - lib/slack/block_kit/layout/section.rb
89
108
  - lib/slack/block_kit/layout/section/multi_select_elements.rb
90
109
  - lib/slack/block_kit/layout/video.rb
@@ -101,7 +120,7 @@ licenses:
101
120
  - MIT
102
121
  metadata:
103
122
  rubygems_mfa_required: 'true'
104
- post_install_message:
123
+ post_install_message:
105
124
  rdoc_options: []
106
125
  require_paths:
107
126
  - lib
@@ -116,8 +135,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
135
  - !ruby/object:Gem::Version
117
136
  version: '0'
118
137
  requirements: []
119
- rubygems_version: 3.4.12
120
- signing_key:
138
+ rubygems_version: 3.5.22
139
+ signing_key:
121
140
  specification_version: 4
122
141
  summary: A ruby wrapper for Slack's Block Kit
123
142
  test_files: []