slack_message 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1d15c6c55f10954900c551dd0547ac3b3b4b83761f72dff1c2e7628634f1014
4
- data.tar.gz: ebeedb567588d122f15906069056c8f4061b98e9b52f2f4affefcf010a260357
3
+ metadata.gz: 30f694caf399c0408dab35d5f63be0dc5a06b0c3611f3fd43a9533877f5ca7b1
4
+ data.tar.gz: 18a0dbd642a9b505ec21c114cf36fc36b9a4319c02a6f9fa057ac8abe6136957
5
5
  SHA512:
6
- metadata.gz: 44a9ac634c8bdd1c3225dab9421b838e1399199dd509f219aaf22f6b8e4e6947eefc6db73660f2e92b211d49bb1a454b9f40fc33cb3e0d049b4c4bc2b5c7aa0d
7
- data.tar.gz: 244d9a37799a75f90715aa16ea5426234cdb806aef3e00b74c38d45f98eac094e2181a85d191c3f03e1687fe7fbb20d2e3e97abdb3c1fe876dbcc1a2f880865b
6
+ metadata.gz: 2768ef640f9e2ba0d79227c14f38c4c3288a218464251be81d4f9d182814b1b4540588b16a834e1077d45ce77a82da716de63ebb4fd0de513a261f4da2dd5abf
7
+ data.tar.gz: a62d68742f30637398c4a337b9fd815c4b0f035aabe51a1d0be2693c3a72d2fbb8fcbe54cccd9c8e6983c44c1d199909f9e36792ba86d396764cf37549af2966
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ slack_message*.gem
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.7.3
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased]
4
+
5
+ ## [1.2.0] - 2021-09-26
6
+ - Turns out gemspec was broken. Fixed that.
7
+
8
+ ## [1.1.0] - 2021-09-26
9
+ - Expanded the README significantly w/ usage instructions
10
+ - Added lots of error handling to requests.
11
+
12
+ ## [1.0.0] - 2021-09-25
13
+
14
+ - Added the base gem w/ a DSL for constructing blocks using sections.
15
+ - Added a changelog, apparently.
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at jmmastey@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,40 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ slack_message (1.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ coderay (1.1.3)
10
+ diff-lcs (1.4.4)
11
+ method_source (1.0.0)
12
+ pry (0.14.1)
13
+ coderay (~> 1.1)
14
+ method_source (~> 1.0)
15
+ rb-readline (0.5.5)
16
+ rspec (3.10.0)
17
+ rspec-core (~> 3.10.0)
18
+ rspec-expectations (~> 3.10.0)
19
+ rspec-mocks (~> 3.10.0)
20
+ rspec-core (3.10.1)
21
+ rspec-support (~> 3.10.0)
22
+ rspec-expectations (3.10.1)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.10.0)
25
+ rspec-mocks (3.10.2)
26
+ diff-lcs (>= 1.2.0, < 2.0)
27
+ rspec-support (~> 3.10.0)
28
+ rspec-support (3.10.2)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ pry (= 0.14.1)
35
+ rb-readline (= 0.5.5)
36
+ rspec (= 3.10.0)
37
+ slack_message!
38
+
39
+ BUNDLED WITH
40
+ 2.1.4
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2021 Joseph Mastey
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 ADDED
@@ -0,0 +1,205 @@
1
+ SlackMessage: a Friendly DSL for Slack
2
+ =============
3
+
4
+ SlackMessage is a wrapper over the [Block Kit
5
+ API](https://app.slack.com/block-kit-builder/) to make it easy to read and
6
+ write messages to slack in your ruby application. It has zero dependencies and
7
+ is built to be opinionated to keep your configuration needs low.
8
+
9
+ To install, just add `slack_message` to your bundle and you're ready to go.
10
+
11
+
12
+ Usage
13
+ ------------
14
+
15
+ ### Configuration
16
+
17
+ To get started, you'll need to configure at least one profile to use to post
18
+ to slack. Get a [Webhook URL](https://slack.com/help/articles/115005265063-Incoming-webhooks-for-Slack)
19
+ from Slack and configure it like this:
20
+
21
+ ```ruby
22
+ SlackMessage.configure do |config|
23
+ webhook_url = 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX'
24
+
25
+ config.add_profile(name: 'Slack Notifier', url: webhook_url)
26
+ end
27
+ ```
28
+
29
+ You should probably keep that webhook in a safe place like `ENV`. If using this
30
+ gem with Rails, place this code in somewhere like
31
+ `config/initializers/slack_message.rb`.
32
+
33
+ #### Additional Profiles
34
+
35
+ If you want to post to multiple different webhook addresses (say, if you have
36
+ several different bots that post to different channels as different identities),
37
+ you can configure those profiles as well, by giving each of them a name:
38
+
39
+ ```ruby
40
+ SlackMessage.configure do |config|
41
+ # default profile
42
+ config.add_profile(name: 'Slack Notifier', url: ENV['SLACK_WEBHOOK_URL'])
43
+
44
+ # additional profiles (see below for usage)
45
+ config.add_profile(:prod_alert_bot, name: 'Prod Alert Bot', url: ENV['SLACK_PROD_ALERT_WEBHOOK_URL'])
46
+ config.add_profile(:sidekiq_bot, name: 'Sidekiq Bot', url: ENV['SLACK_SIDEKIQ_WEBHOOK_URL'])
47
+ end
48
+ ```
49
+
50
+ #### Configuring User Search
51
+
52
+ Slack's API no longer allows you to send DMs to users by username. You need to
53
+ look up a user's internal ID and send to that ID. Thankfully, there is a lookup
54
+ by email endpoint for this. If you'd like to post messages to users by their
55
+ email address, you'll need a
56
+ [separate API Token](https://api.slack.com/tutorials/tracks/getting-a-token):
57
+
58
+ ```ruby
59
+ SlackMessage.configure do |config|
60
+ config.api_token = 'xoxb-11111111111-2222222222-33333333333333333'
61
+ end
62
+ ```
63
+
64
+ ### Usage
65
+
66
+ Basic usage is pretty straightforward:
67
+
68
+ ```ruby
69
+ SlackMessage.post_to('#general') do
70
+ text "We did it! :thumbsup:"
71
+ end
72
+ ```
73
+
74
+ That's it! SlackMessage will automatically serialize for the API like this:
75
+
76
+ ```json
77
+ [{"type":"section","text":{"type":"mrkdwn","text":"We did it! :thumbsup:"}}]
78
+ ```
79
+
80
+ Details like remembering that Slack made a mystifying decision to force you to
81
+ request "mrkdwn", or requiring your text to be wrapped into a section are handled
82
+ for you.
83
+
84
+ Building up messages is meant to be as user-friendly as possible:
85
+
86
+ ```ruby
87
+ SlackMessage.build do
88
+ text "haiku are easy"
89
+ text "but sometimes they don't make sense"
90
+ text "refrigerator"
91
+
92
+ context "- unknown author"
93
+ end
94
+ ```
95
+
96
+ SlackMessage will combine your text declarations and add any necessary wrappers
97
+ automatically:
98
+
99
+ ```json
100
+ [
101
+ {
102
+ "type": "section",
103
+ "text": {
104
+ "type": "mrkdwn",
105
+ "text": "haiku are easy\nbut sometimes they don't make sense\nrefrigerator"
106
+ }
107
+ },
108
+ {
109
+ "type": "context",
110
+ "elements": [
111
+ {
112
+ "type": "mrkdwn",
113
+ "text": "- unknown author"
114
+ }
115
+ ]
116
+ }
117
+ ]
118
+ ```
119
+
120
+ If you've configured an API key for user search (see above in configuration),
121
+ it's just as easy to send messages directly to users:
122
+
123
+ ```ruby
124
+ SlackMessage.post_to('hello@joemastey.com') do
125
+ text "We did it! :thumbsup:"
126
+ end
127
+ ```
128
+
129
+ SlackMessage is able to build all kinds of rich messages for you, and has been
130
+ a real joy to use for the author at least. To understand a bit more about the
131
+ possibilities of blocks, see Slack's [Block Kit
132
+ Builder](https://app.slack.com/block-kit-builder/) to understand the structure
133
+ better:
134
+
135
+ ```ruby
136
+ SlackMessage.post_to('#general') do
137
+ section do
138
+ text "A job has generated some output for you to review."
139
+ text 'And More' * 10
140
+ link_button "See Results", "https://google.com"
141
+ end
142
+
143
+ section do
144
+ text ":unlock-new: New Data Summary"
145
+
146
+ list_item "Date", "09/05/2021"
147
+ list_item "Total Imported", 45_004
148
+ list_item "Total Errors", 5
149
+ end
150
+
151
+ divider
152
+
153
+ section do
154
+ text "See more here: #{link('result', 'https://google.com')}"
155
+ end
156
+
157
+ text ":rocketship: hello@joemastey.com"
158
+
159
+ context ":custom_slack_emoji: An example footer *with some markdown*."
160
+ end
161
+ ```
162
+
163
+ SlackMessage will compose this into Block Kit syntax and send it on its way!
164
+ For now you'll need to read a bit of the source code to get the entire API. Sorry,
165
+ working on it.
166
+
167
+ If you've defined multiple profiles in configuration, you can specify which to
168
+ use for your message by specifying their name:
169
+
170
+ ```ruby
171
+ SlackMessage.post_to('#general', as: :sidekiq_bot) do
172
+ text ":octagonal_sign: A job has failed permanently and needs to be rescued."
173
+ link_button "Sidekiq Dashboard", "https://yoursite.com/sidekiq", style: :danger
174
+ end
175
+ ```
176
+
177
+
178
+ What it Doesn't Do
179
+ ------------
180
+
181
+ This gem is intended to stay fairly simple. Other gems have lots of config
182
+ options and abilities, which is wonderful, but overall complicates usage. If
183
+ you want to add a feature, open an issue on Github first to see if it's likely
184
+ to be merged.
185
+
186
+ Since this gem was built out of an existing need that _didn't_ include most of
187
+ the block API, I'd be inclined to merge features that sustainably expand the
188
+ DSL to include more of the block API itself.
189
+
190
+ Also, some behaviors that are still planned but not yet added:
191
+
192
+ * allow custom http_options in configuration
193
+ * allow custom slack username per built message
194
+
195
+ Contributing
196
+ ------------
197
+
198
+ Contributions are very welcome. Fork, fix, submit pulls.
199
+
200
+ Contribution is expected to conform to the [Contributor Covenant](https://github.com/jmmastey/slack_message/blob/master/CODE_OF_CONDUCT.md).
201
+
202
+ License
203
+ ------------
204
+
205
+ This software is released under the [MIT License](https://github.com/jmmastey/slack_message/blob/master/MIT-LICENSE).
@@ -0,0 +1,57 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+
4
+ class SlackMessage::Api
5
+ def self.user_id_for(email)
6
+ token = SlackMessage.configuration.api_token
7
+
8
+ uri = URI("https://slack.com/api/users.lookupByEmail?email=#{email}")
9
+ request = Net::HTTP::Get.new(uri).tap do |req|
10
+ req['Authorization'] = "Bearer #{token}"
11
+ req['Content-type'] = "application/json"
12
+ end
13
+
14
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
15
+ http.request(request)
16
+ end
17
+
18
+ if response.code != "200"
19
+ raise "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
20
+ end
21
+
22
+ payload = JSON.parse(response.body)
23
+ if payload.include?("error") && payload["error"] == "invalid_auth"
24
+ raise "Received an error because your authentication token isn't properly configured:\n#{response.body}"
25
+ elsif payload.include?("error")
26
+ raise "Received error response from Slack during user lookup:\n#{response.body}"
27
+ end
28
+
29
+ payload["user"]["id"]
30
+ end
31
+
32
+ def self.post(payload, target, profile)
33
+ profile[:url] = profile[:url]
34
+
35
+ uri = URI.parse(profile[:url])
36
+ params = {
37
+ channel: target,
38
+ username: profile[:name],
39
+ blocks: payload
40
+ }.to_json
41
+
42
+ response = Net::HTTP.post_form uri, { payload: params }
43
+
44
+ # let's try to be helpful about error messages
45
+ if response.body == "invalid_token"
46
+ raise "Couldn't send slack message because the URL for profile '#{profile[:handle]}' is wrong."
47
+ elsif response.body == "channel_not_found"
48
+ raise "Tried to send Slack message to non-existent channel or user '#{target}'"
49
+ elsif response.body == "missing_text_or_fallback_or_attachments"
50
+ raise "Tried to send Slack message with invalid payload."
51
+ elsif response.code != "200"
52
+ raise "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
53
+ end
54
+
55
+ response
56
+ end
57
+ end
@@ -0,0 +1,45 @@
1
+ module SlackMessage::Configuration
2
+ @@api_token = nil
3
+ @@profiles = {}
4
+
5
+ def self.reset
6
+ @@api_token = nil
7
+ @@profiles = {}
8
+ end
9
+
10
+ def self.configure
11
+ yield self
12
+ end
13
+
14
+ ###
15
+
16
+ def self.api_token=(token)
17
+ @@api_token = token
18
+ end
19
+
20
+ def self.api_token
21
+ unless @@api_token.is_a? String
22
+ raise ArgumentError, "Please set an API token to use API features."
23
+ end
24
+
25
+ @@api_token
26
+ end
27
+
28
+ ###
29
+
30
+ def self.add_profile(handle = :default, name:, url:)
31
+ if @@profiles.include?(handle)
32
+ warn("WARNING: Overriding profile '#{handle}' in SlackMessage config")
33
+ end
34
+
35
+ @@profiles[handle] = { name: name, url: url, handle: handle }
36
+ end
37
+
38
+ def self.profile(handle)
39
+ unless @@profiles.include?(handle)
40
+ raise ArgumentError, "Unknown SlackMessage profile '#{handle}'."
41
+ end
42
+
43
+ @@profiles[handle]
44
+ end
45
+ end
@@ -0,0 +1,150 @@
1
+ class SlackMessage::Dsl
2
+ attr_reader :body, :default_section
3
+
4
+ def initialize
5
+ @body = []
6
+ @default_section = Section.new
7
+ end
8
+
9
+ # allowable top-level entities within a block
10
+
11
+ def section(&block)
12
+ finalize_default_section
13
+
14
+ section = Section.new.tap do |s|
15
+ s.instance_eval(&block)
16
+ end
17
+
18
+ @body.push(section.render)
19
+ end
20
+
21
+ def divider
22
+ finalize_default_section
23
+
24
+ @body.push({ type: "divider" })
25
+ end
26
+
27
+ def context(text)
28
+ finalize_default_section
29
+
30
+ @body.push({ type: "context", elements: [{
31
+ type: "mrkdwn", text: text
32
+ }]})
33
+ end
34
+
35
+ # end entities
36
+
37
+ # delegation to allow terse syntax without e.g. `section`
38
+
39
+ def text(*args); default_section.text(*args); end
40
+ def link_button(*args); default_section.link_button(*args); end
41
+ def blank_line(*args); default_section.blank_line(*args); end
42
+ def link(*args); default_section.link(*args); end
43
+ def list_item(*args); default_section.list_item(*args); end
44
+
45
+ # end delegation
46
+
47
+ private
48
+
49
+ # when doing things that would generate new top-levels, first try
50
+ # to finish the implicit section.
51
+ def finalize_default_section
52
+ if default_section.has_content?
53
+ @body.push(default_section.body)
54
+ end
55
+
56
+ @default_section = Section.new
57
+ end
58
+
59
+ def render
60
+ finalize_default_section
61
+ @body
62
+ end
63
+
64
+ class Section
65
+ attr_reader :body
66
+
67
+ def initialize
68
+ @body = { type: "section" }
69
+ @list = List.new
70
+ end
71
+
72
+ def text(msg)
73
+ if @body.include?(:text)
74
+ @body[:text][:text] << "\n#{msg}"
75
+
76
+ else
77
+ @body.merge!({ text: { type: "mrkdwn", text: msg } })
78
+ end
79
+ end
80
+
81
+ # styles: default, primary, danger
82
+ def link_button(label, target, style: :primary)
83
+ config = {
84
+ accessory: {
85
+ type: "button",
86
+ url: target,
87
+ text: {
88
+ type: "plain_text",
89
+ text: label,
90
+ emoji: true
91
+ },
92
+ }
93
+ }
94
+
95
+ if style != :default
96
+ config[:accessory][:style] = style
97
+ end
98
+
99
+ @body.merge!(config)
100
+ end
101
+
102
+ # for markdown links
103
+ def link(label, target)
104
+ "<#{target}|#{label}>"
105
+ end
106
+
107
+ def list_item(title, value)
108
+ @list.add(title, value)
109
+ end
110
+
111
+ def blank_line
112
+ text " " # unicode emspace
113
+ end
114
+
115
+ def has_content?
116
+ @body.keys.length > 1 || @list.any?
117
+ end
118
+
119
+ def render
120
+ body[:fields] = @list.render if @list.any?
121
+ body
122
+ end
123
+ end
124
+
125
+ class List
126
+ def initialize
127
+ @items = []
128
+ end
129
+
130
+ def any?
131
+ @items.any?
132
+ end
133
+
134
+ def add(title, value)
135
+ @items.push(["*#{title}*", value])
136
+ end
137
+
138
+ def render
139
+ @items.push([' ', ' ']) if @items.length % 2 == 1
140
+ @items.each_slice(2).flat_map do |(first, second)|
141
+ [
142
+ { type: "mrkdwn", text: first[0] },
143
+ { type: "mrkdwn", text: second[0] },
144
+ { type: "mrkdwn", text: first[1] },
145
+ { type: "mrkdwn", text: second[1] },
146
+ ]
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.name = 'slack_message'
3
+ gem.version = "1.2.0"
4
+ gem.summary = "A nice DSL for composing rich messages in Slack"
5
+ gem.authors = ["Joe Mastey"]
6
+ gem.email = 'hello@joemastey.com'
7
+ gem.homepage = 'https://rubygemgem.org/gems/slack_message'
8
+ gem.licenses = 'MIT'
9
+
10
+ glob = lambda { |patterns| gem.files & Dir[*patterns] }
11
+
12
+ gem.files = `git ls-files`.split($/)
13
+ gem.test_files = glob['{spec/{**/}*_spec.rb']
14
+
15
+ gem.metadata = {
16
+ "homepage_uri" => "http://github.com/jmmastey/slack_message",
17
+ "changelog_uri" => "https://github.com/jmmastey/slack_message/blob/master/CHANGELOG.md",
18
+ "source_code_uri" => "http://github.com/jmmastey/slack_message",
19
+ }
20
+
21
+ gem.add_development_dependency "rspec", "3.10.0"
22
+ gem.add_development_dependency "pry", "0.14.1"
23
+ gem.add_development_dependency "rb-readline", "0.5.5"
24
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe SlackMessage do
4
+ it "includes a bunch of stuff" do
5
+ expect(SlackMessage).to respond_to(:post_to)
6
+ end
7
+
8
+ describe "API convenience" do
9
+ it "can grab user IDs" do
10
+ allow(SlackMessage::Api).to receive(:api_request)
11
+ .with(/hello@joemastey.com/)
12
+ .and_return({ "user" => { "id" => "ABC123" }})
13
+
14
+ result = SlackMessage.user_id_for("hello@joemastey.com")
15
+ expect(result).to eq("ABC123")
16
+ end
17
+ end
18
+
19
+ describe "DSL" do
20
+ describe "#build" do
21
+ it "renders some JSON" do
22
+ expected_output = [
23
+ { type: "section",
24
+ text: { text: "foo", type: "mrkdwn" }
25
+ }
26
+ ]
27
+
28
+ output = SlackMessage.build do
29
+ text "foo"
30
+ end
31
+
32
+ expect(output).to eq(expected_output)
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "configuration" do
38
+ after do
39
+ SlackMessage.configuration.reset
40
+ end
41
+
42
+ it "allows you to set an API key" do
43
+ SlackMessage.configure do |config|
44
+ config.api_token = "abc123"
45
+ end
46
+
47
+ expect(SlackMessage.configuration.api_token).to eq("abc123")
48
+ end
49
+
50
+ it "raises errors for missing configuration" do
51
+ SlackMessage.configure do |config|
52
+ #config.api_token = "abc123"
53
+ end
54
+
55
+ expect {
56
+ SlackMessage.configuration.api_token
57
+ }.to raise_error(ArgumentError)
58
+ end
59
+
60
+ it "lets you add and fetch profiles" do
61
+ SlackMessage.configure do |config|
62
+ config.add_profile(name: 'default profile', url: 'http://hooks.slack.com/1234/')
63
+ config.add_profile(:nonstandard, name: 'another profile', url: 'http://hooks.slack.com/1234/')
64
+ end
65
+
66
+
67
+ expect(SlackMessage.configuration.profile(:default)[:name]).to eq('default profile')
68
+ expect(SlackMessage.configuration.profile(:nonstandard)[:name]).to eq('another profile')
69
+
70
+ expect {
71
+ SlackMessage.configuration.profile(:missing)
72
+ }.to raise_error(ArgumentError)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,52 @@
1
+ require_relative '../lib/slack_message'
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
6
+ # this file to always be loaded, without a need to explicitly require it in any
7
+ # files.
8
+ #
9
+ # Given that it is always loaded, you are encouraged to keep this file as
10
+ # light-weight as possible. Requiring heavyweight dependencies from this file
11
+ # will add to the boot time of your test suite on EVERY test run, even for an
12
+ # individual file that may not need all of that loaded. Instead, consider making
13
+ # a separate helper file that requires the additional dependencies and performs
14
+ # the additional setup, and require it from the spec files that actually need
15
+ # it.
16
+ #
17
+ # The `.rspec` file also contains a few flags that are not defaults but that
18
+ # users commonly want.
19
+ #
20
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
21
+
22
+ RSpec.configure do |config|
23
+ # This allows you to limit a spec run to individual examples or groups
24
+ # you care about by tagging them with `:focus` metadata. When nothing
25
+ # is tagged with `:focus`, all examples get run. RSpec also provides
26
+ # aliases for `it`, `describe`, and `context` that include `:focus`
27
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
28
+ config.filter_run_when_matching :focus
29
+
30
+ # Limits the available syntax to the non-monkey patched syntax that is
31
+ # recommended. For more details, see:
32
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
33
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
34
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
35
+ config.disable_monkey_patching!
36
+
37
+ # This setting enables warnings. It's recommended, but in some cases may
38
+ # be too noisy due to issues in dependencies.
39
+ config.warnings = true
40
+
41
+ # Run specs in random order to surface order dependencies. If you find an
42
+ # order dependency and want to debug it, you can fix the order by providing
43
+ # the seed, which is printed after each run.
44
+ # --seed 1234
45
+ config.order = :random
46
+
47
+ # Seed global randomization in this process using the `--seed` CLI option.
48
+ # Setting this allows you to use `--seed` to deterministically reproduce
49
+ # test failures related to randomization by passing the same `--seed` value
50
+ # as the one that triggered the failure.
51
+ Kernel.srand config.seed
52
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slack_message
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Mastey
@@ -58,7 +58,21 @@ executables: []
58
58
  extensions: []
59
59
  extra_rdoc_files: []
60
60
  files:
61
+ - ".gitignore"
62
+ - ".ruby-version"
63
+ - CHANGELOG.md
64
+ - CODE_OF_CONDUCT.md
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - MIT-LICENSE
68
+ - README.md
61
69
  - lib/slack_message.rb
70
+ - lib/slack_message/api.rb
71
+ - lib/slack_message/configuration.rb
72
+ - lib/slack_message/dsl.rb
73
+ - slack_message.gemspec
74
+ - spec/slack_message_spec.rb
75
+ - spec/spec_helper.rb
62
76
  homepage: https://rubygemgem.org/gems/slack_message
63
77
  licenses:
64
78
  - MIT