slack-ruby-block-kit 0.22.0 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) 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 +23 -2
  5. data/Gemfile +4 -1
  6. data/Gemfile.lock +55 -20
  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 +11 -2
  15. data/lib/slack/block_kit/element/radio_buttons.rb +3 -2
  16. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/channel.rb +32 -0
  17. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/emoji.rb +27 -0
  18. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/link.rb +36 -0
  19. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/style_helper.rb +25 -0
  20. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/text.rb +32 -0
  21. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/user.rb +32 -0
  22. data/lib/slack/block_kit/layout/rich_text/rich_text_elements/usergroup.rb +32 -0
  23. data/lib/slack/block_kit/layout/rich_text/rich_text_elements.rb +36 -0
  24. data/lib/slack/block_kit/layout/rich_text/rich_text_list.rb +51 -0
  25. data/lib/slack/block_kit/layout/rich_text/rich_text_preformatted.rb +38 -0
  26. data/lib/slack/block_kit/layout/rich_text/rich_text_quote.rb +38 -0
  27. data/lib/slack/block_kit/layout/rich_text/rich_text_section.rb +36 -0
  28. data/lib/slack/block_kit/layout/rich_text.rb +73 -0
  29. data/lib/slack/block_kit/version.rb +1 -1
  30. metadata +26 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0bc7d017312a1b9050129594164e9b4eff6516df696e52a72eeced5b434a862d
4
- data.tar.gz: c6b04c9e520b33be39ef4efcf492b798e70558ae61024e137eb71ecac3fdb9d8
3
+ metadata.gz: 8d0af3b832aa23bc5cc33c2f9aee6c1ecfd2f94b9b060fec44564f6ad4c949e5
4
+ data.tar.gz: d444d3b97c923d8c73ff66fa7b55055bda5f4179fbdd012fd5ef55ba47599dd8
5
5
  SHA512:
6
- metadata.gz: 5aa13638ce2aad5b93175bd66b16320533693e81e20f3ec95df4f6c916f85da31c47d15aec93933b79b2d3d34da320588036e32666baa5b18bb5c81f3c4cd89d
7
- data.tar.gz: 6a2c6f5fbb5e7447069d421e1ec9cb99d44b4eec3f62b49a6df34e31b27336e2a12fd7f870398baafbdabc87b50d881d9c2537e121164d7e7ed7adbbe6249c14
6
+ metadata.gz: 2235db0ad29dfecb153e92f1e8bbfe68fab93a65b38fc714150fd3356ed13f6f0ec71144690b01cfe93da785524a7dfc27fa6a4c554dff50a34b563f2b3a4971
7
+ data.tar.gz: fa817ee8bc0bf6694a1bf27b9d42a5a5a90023e1537df2c6a494351647bec67faa9e6ddbf7fd954230f717beea027fd2b87b1d84bedc86f4c0bf4cc8a327cea1
@@ -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,7 +25,26 @@ 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.22.0] - 2023-08-5
28
+
29
+ ## [0.24.0] - 2024-04-07
30
+
31
+ ### Added
32
+
33
+ - Added support for Rich Text Block via `Slack::BlockKit::Layout::RichText` (#185 by @GetOutOfMyBakery)
34
+
35
+
36
+ ### Changed
37
+ - Codecov reporting via GitHub Actions OIDC (#188 by @CGA1123)
38
+ - Rubygems releasing via GitHub Actions OIDC (#188 by @CGA1123)
39
+
40
+ ## [0.23.0] - 2023-08-07
41
+
42
+ ### Added
43
+
44
+ - Added ability to set `emoji` property via `Slack::BlockKit::Blocks#input` (#175 by @bmorton)
45
+ - Added ability to set `emoji` property via `Slack::BlockKit::Element::RadioButtons#option` (#175 by @bmorton)
46
+
47
+ ## [0.22.0] - 2023-08-05
29
48
 
30
49
  ### Added
31
50
  - Added `Slack::BlockKit::Element::NumberInput` (#169 by @CGA1123)
@@ -173,7 +192,9 @@ This release contains a breaking change on the `Layout::Actions` interface.
173
192
  - Fixed initial options in multi select blocks (#46 by @caalberts)
174
193
 
175
194
 
176
- [Unreleased]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.22.0...HEAD
195
+ [Unreleased]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.24.0...HEAD
196
+ [0.23.0]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.23.0...v0.24.0
197
+ [0.23.0]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.22.0...v0.23.0
177
198
  [0.22.0]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.21.0...v0.22.0
178
199
  [0.21.0]: https://github.com/CGA1123/slack-ruby-block-kit/compare/v0.20.0...v0.21.0
179
200
  [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
20
  gem 'simplecov', '~> 0.21', 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.22.0)
4
+ slack-ruby-block-kit (0.24.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,55 @@ 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.7.3)
48
61
  rainbow (3.1.1)
49
- rake (13.0.6)
62
+ rake (13.2.0)
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)
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)
51
76
  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.0)
57
- rspec-support (~> 3.12.0)
58
- rspec-expectations (3.12.0)
77
+ rspec (3.13.0)
78
+ rspec-core (~> 3.13.0)
79
+ rspec-expectations (~> 3.13.0)
80
+ rspec-mocks (~> 3.13.0)
81
+ rspec-core (3.13.0)
82
+ rspec-support (~> 3.13.0)
83
+ rspec-expectations (3.13.0)
59
84
  diff-lcs (>= 1.2.0, < 2.0)
60
- rspec-support (~> 3.12.0)
61
- rspec-mocks (3.12.0)
85
+ rspec-support (~> 3.13.0)
86
+ rspec-mocks (3.13.0)
62
87
  diff-lcs (>= 1.2.0, < 2.0)
63
- rspec-support (~> 3.12.0)
64
- rspec-support (3.12.0)
88
+ rspec-support (~> 3.13.0)
89
+ rspec-support (3.13.0)
65
90
  rspec_junit_formatter (0.6.0)
66
91
  rspec-core (>= 2, < 4, != 2.12.0)
67
92
  rubocop (1.28.2)
@@ -85,29 +110,39 @@ GEM
85
110
  docile (~> 1.1)
86
111
  simplecov-html (~> 0.11)
87
112
  simplecov_json_formatter (~> 0.1)
113
+ simplecov-cobertura (2.1.0)
114
+ rexml
115
+ simplecov (~> 0.19)
88
116
  simplecov-html (0.12.3)
89
- simplecov_json_formatter (0.1.3)
117
+ simplecov_json_formatter (0.1.4)
118
+ string-similarity (2.1.0)
119
+ stringio (3.1.0)
120
+ tty-option (0.3.0)
90
121
  unicode-display_width (2.1.0)
91
- zeitwerk (2.6.11)
122
+ zeitwerk (2.6.13)
92
123
 
93
124
  PLATFORMS
94
125
  ruby
95
126
  x86_64-darwin-19
127
+ x86_64-darwin-23
96
128
  x86_64-linux
97
129
 
98
130
  DEPENDENCIES
99
- codecov (~> 0.6)
131
+ debug (~> 1.9)
100
132
  dotenv (~> 2)
101
133
  faraday (~> 1)
102
134
  pry (~> 0.14)
135
+ racc
103
136
  rake (~> 13)
137
+ retest (~> 1.13)
104
138
  rspec (~> 3)
105
139
  rspec_junit_formatter (~> 0.6)
106
140
  rubocop (~> 1)
107
141
  rubocop-rake (~> 0.6)
108
142
  rubocop-rspec (~> 2)
109
143
  simplecov (~> 0.21)
144
+ simplecov-cobertura
110
145
  slack-ruby-block-kit!
111
146
 
112
147
  BUNDLED WITH
113
- 2.2.3
148
+ 2.4.18
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,
@@ -76,13 +84,14 @@ module Slack
76
84
  append(block)
77
85
  end
78
86
 
79
- def input(label:, hint: nil, block_id: nil, dispatch_action: nil, optional: nil)
87
+ def input(label:, hint: nil, block_id: nil, dispatch_action: nil, optional: nil, emoji: nil)
80
88
  block = Layout::Input.new(
81
89
  label: label,
82
90
  hint: hint,
83
91
  block_id: block_id,
84
92
  dispatch_action: dispatch_action,
85
- optional: optional
93
+ optional: optional,
94
+ emoji: emoji
86
95
  )
87
96
 
88
97
  yield(block) if block_given?
@@ -21,11 +21,12 @@ module Slack
21
21
  yield(self) if block_given?
22
22
  end
23
23
 
24
- def option(value:, text:, initial: false)
24
+ def option(value:, text:, initial: false, emoji: nil)
25
25
  option = Composition::Option.new(
26
26
  value: value,
27
27
  text: text,
28
- initial: initial
28
+ initial: initial,
29
+ emoji: emoji
29
30
  )
30
31
 
31
32
  @options << option
@@ -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.22.0'
5
+ VERSION = '0.24.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.22.0
4
+ version: 0.24.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-05 00:00:00.000000000 Z
11
+ date: 2024-04-07 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.3
139
+ signing_key:
121
140
  specification_version: 4
122
141
  summary: A ruby wrapper for Slack's Block Kit
123
142
  test_files: []