lita-slack 1.5.0 → 1.6.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
  SHA1:
3
- metadata.gz: 8c3600cd068e9891e914063b341e384e1e66c117
4
- data.tar.gz: 0dcbfb0f922578b75ec22a835d7d77e7072c22fd
3
+ metadata.gz: 263b8f5a62893a0ca957dbbf02925525e6c4aef0
4
+ data.tar.gz: 8a8d23b254f44196cb4c332c81b445fbac276df0
5
5
  SHA512:
6
- metadata.gz: 7b285b424783c62984f4f31b1dec16937c6ea8807f74b428fd769b83d60dc5ca2793c695ed4ae79efb52c0079c9ddfb813782379aa72c1ebf325a73f3eb17a9b
7
- data.tar.gz: 67da2107713a27eab01d59b19c9256593778341b437c7aeb6f6f832f05eafb359038aa36466fbccd0b5841481712048a4b7590aabd26824b1fc954bb8390e512
6
+ metadata.gz: 09b05e48245ee0966a4a211a6672df6d8042e5a5af27f74c88ea91ad568fe865e0fce44e709e32a5f18afca9198c15826a2c02b3ba60cf423448923e078486ee
7
+ data.tar.gz: 8408c30ff79ef6b025e7e94c29178538b84d01f850ef24e6e41f6ee365b59cf6b3e5d1945605f12efa113b0669422c6e3c67fdef105f6d4a69575ed21c2faf8f
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
+ sudo: false
2
3
  rvm:
3
4
  - 2.0.0
4
5
  script: bundle exec rake
data/README.md CHANGED
@@ -50,6 +50,14 @@ Lita will join your default channel after initial setup. To have it join additio
50
50
  * `:slack_user_created` - When the robot creates/updates a user's info - name, mention name, etc., as directed by Slack. The payload has a single object, a `Lita::Slack::Adapters::SlackUser` object, under the `:slack_user` key.
51
51
  * `:slack_channel_created` - When the robot creates/updates a channel's or group's info, as directed by Slack. The payload has a single object, a `Lita::Slack::Adapters::SlackChannel` object, under the `:slack_channel` key.
52
52
 
53
+ ## Chat service API
54
+
55
+ lita-slack supports Lita 4.6's chat service API for Slack-specific functionality. You can access this API object by calling the `Lita::Robot#chat_service`. See the API docs for `Lita::Slack::Adapters::ChatService` for details about the provided methods.
56
+
57
+ ## API documentation
58
+
59
+ The API documentation, useful for plugin authors, can be found for the latest gem release on [RubyDoc.info](http://www.rubydoc.info/gems/lita-slack)
60
+
53
61
  ## License
54
62
 
55
63
  [MIT](http://opensource.org/licenses/MIT)
@@ -1,12 +1,20 @@
1
+ require 'lita/adapters/slack/chat_service'
1
2
  require 'lita/adapters/slack/rtm_connection'
2
3
 
3
4
  module Lita
4
5
  module Adapters
6
+ # A Slack adapter for Lita.
7
+ # @api private
5
8
  class Slack < Adapter
6
9
  # Required configuration attributes.
7
10
  config :token, type: String, required: true
8
11
  config :proxy, type: String
9
12
 
13
+ # Provides an object for Slack-specific features.
14
+ def chat_service
15
+ ChatService.new(config)
16
+ end
17
+
10
18
  # Starts the connection.
11
19
  def run
12
20
  return if rtm_connection
@@ -8,6 +8,7 @@ require 'lita/adapters/slack/slack_channel'
8
8
  module Lita
9
9
  module Adapters
10
10
  class Slack < Adapter
11
+ # @api private
11
12
  class API
12
13
  def initialize(config, stubs = nil)
13
14
  @config = config
@@ -20,6 +21,15 @@ module Lita
20
21
  SlackIM.new(response_data["channel"]["id"], user_id)
21
22
  end
22
23
 
24
+ def send_attachments(room_or_user, attachments)
25
+ call_api(
26
+ "chat.postMessage",
27
+ as_user: true,
28
+ channel: room_or_user.id,
29
+ attachments: MultiJson.dump(attachments.map(&:to_hash)),
30
+ )
31
+ end
32
+
23
33
  def set_topic(channel, topic)
24
34
  call_api("channels.setTopic", channel: channel, topic: topic)
25
35
  end
@@ -0,0 +1,36 @@
1
+ module Lita
2
+ module Adapters
3
+ class Slack < Adapter
4
+ # A Slack attachment object.
5
+ # @api public
6
+ # @see https://api.slack.com/docs/attachments
7
+ # @since 1.6.0
8
+ class Attachment
9
+ # @param text [String] The main text of the message.
10
+ # @param options [Hash] Keyword arguments supporting all the option supported by Slack's
11
+ # attachment API. These options will be passed to Slack as provided, with the exception
12
+ # that the +:fallback+ option defaults to the value of +text+ (the first argument to this
13
+ # method) and any value specified for the +:text+ option will be overwritten by the
14
+ # explicit +text+ argument.
15
+ def initialize(text, **options)
16
+ self.text = text
17
+ self.options = options
18
+ end
19
+
20
+ # Converts the attachment into a hash, suitable for being sent to the Slack API.
21
+ # @return [Hash] The converted hash.
22
+ def to_hash
23
+ options.merge({
24
+ fallback: options[:fallback] || text,
25
+ text: text,
26
+ })
27
+ end
28
+
29
+ private
30
+
31
+ attr_accessor :options
32
+ attr_accessor :text
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,29 @@
1
+ require "lita/adapters/slack/attachment"
2
+
3
+ module Lita
4
+ module Adapters
5
+ class Slack < Adapter
6
+ # Slack-specific features made available to +Lita::Robot+.
7
+ # @api public
8
+ # @since 1.6.0
9
+ class ChatService
10
+ attr_accessor :api
11
+
12
+ # @param config [Lita::Configuration] The adapter's configuration data.
13
+ def initialize(config)
14
+ self.api = API.new(config)
15
+ end
16
+
17
+ # @param target [Lita::Room, Lita::User] A room or user object indicating where the
18
+ # attachment should be sent.
19
+ # @param attachments [Attachment, Array<Attachment>] An {Attachment} or array of
20
+ # {Attachment}s to send.
21
+ # @return [void]
22
+ def send_attachments(target, attachments)
23
+ api.send_attachments(target, Array(attachments))
24
+ end
25
+ alias_method :send_attachment, :send_attachments
26
+ end
27
+ end
28
+ end
29
+ end
@@ -3,6 +3,7 @@ require 'eventmachine'
3
3
  module Lita
4
4
  module Adapters
5
5
  class Slack < Adapter
6
+ # @api private
6
7
  class EventLoop
7
8
  class << self
8
9
  def defer
@@ -1,6 +1,7 @@
1
1
  module Lita
2
2
  module Adapters
3
3
  class Slack < Adapter
4
+ # @api private
4
5
  class IMMapping
5
6
  def initialize(api, ims)
6
7
  @api = api
@@ -1,6 +1,7 @@
1
1
  module Lita
2
2
  module Adapters
3
3
  class Slack < Adapter
4
+ # @api private
4
5
  class MessageHandler
5
6
  def initialize(robot, robot_id, data)
6
7
  @robot = robot
@@ -70,7 +71,7 @@ module Lita
70
71
  else
71
72
  user = User.find_by_id(link)
72
73
  if user
73
- "@#{user.name}"
74
+ "@#{user.mention_name}"
74
75
  else
75
76
  "@#{link}"
76
77
  end
@@ -1,6 +1,7 @@
1
1
  module Lita
2
2
  module Adapters
3
3
  class Slack < Adapter
4
+ # @api private
4
5
  class RoomCreator
5
6
  class << self
6
7
  def create_room(channel, robot)
@@ -11,6 +11,7 @@ require 'lita/adapters/slack/user_creator'
11
11
  module Lita
12
12
  module Adapters
13
13
  class Slack < Adapter
14
+ # @api private
14
15
  class RTMConnection
15
16
  MAX_MESSAGE_BYTES = 16_000
16
17
 
@@ -1,8 +1,11 @@
1
1
  module Lita
2
2
  module Adapters
3
3
  class Slack < Adapter
4
+ # A struct representing a Slack channel, group, or IM.
5
+ # @api public
4
6
  class SlackChannel
5
7
  class << self
8
+ # @api private
6
9
  def from_data(channel_data)
7
10
  new(
8
11
  channel_data['id'],
@@ -13,15 +16,21 @@ module Lita
13
16
  )
14
17
  end
15
18
 
19
+ # @api private
16
20
  def from_data_array(channels_data)
17
21
  channels_data.map { |channel_data| from_data(channel_data) }
18
22
  end
19
23
  end
20
24
 
25
+ # @return [String] The channel's unique ID.
21
26
  attr_reader :id
27
+ # @return [String] The human-readable name for the channel.
22
28
  attr_reader :name
29
+ # @return [String] A timestamp indicating when the channel was created.
23
30
  attr_reader :created
31
+ # @return [String] The unique ID of the user who created the channel.
24
32
  attr_reader :creator
33
+ # @return [Hash] The raw channel data received from Slack, including many more fields.
25
34
  attr_reader :raw_data
26
35
 
27
36
  def initialize(id, name, created, creator, raw_data)
@@ -34,4 +43,4 @@ module Lita
34
43
  end
35
44
  end
36
45
  end
37
- end
46
+ end
@@ -1,6 +1,7 @@
1
1
  module Lita
2
2
  module Adapters
3
3
  class Slack < Adapter
4
+ # @api private
4
5
  class SlackIM
5
6
  class << self
6
7
  def from_data_array(ims_data)
@@ -1,8 +1,11 @@
1
1
  module Lita
2
2
  module Adapters
3
3
  class Slack < Adapter
4
+ # A struct representing a Slack user.
5
+ # @api public
4
6
  class SlackUser
5
7
  class << self
8
+ # @api private
6
9
  def from_data(user_data)
7
10
  new(
8
11
  user_data['id'],
@@ -12,14 +15,19 @@ module Lita
12
15
  )
13
16
  end
14
17
 
18
+ # @api private
15
19
  def from_data_array(users_data)
16
20
  users_data.map { |user_data| from_data(user_data) }
17
21
  end
18
22
  end
19
23
 
24
+ # @return [String] The user's unique ID.
20
25
  attr_reader :id
26
+ # @return [String] The user's mention name, e.g. @alice.
21
27
  attr_reader :name
28
+ # @return [String] The user's display name, e.g. Alice Bobhart
22
29
  attr_reader :real_name
30
+ # @return [Hash] The raw user data received from Slack, including many more fields.
23
31
  attr_reader :raw_data
24
32
 
25
33
  def initialize(id, name, real_name, raw_data)
@@ -1,5 +1,6 @@
1
1
  module Lita
2
2
  module Adapters
3
+ # @api private
3
4
  class Slack < Adapter
4
5
  TeamData = Struct.new(:ims, :self, :users, :channels, :websocket_url)
5
6
  end
@@ -1,6 +1,7 @@
1
1
  module Lita
2
2
  module Adapters
3
3
  class Slack < Adapter
4
+ # @api private
4
5
  class UserCreator
5
6
  class << self
6
7
  def create_user(slack_user, robot, robot_id)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "lita-slack"
3
- spec.version = "1.5.0"
3
+ spec.version = "1.6.0"
4
4
  spec.authors = ["Ken J.", "Jimmy Cuadra"]
5
5
  spec.email = ["kenjij@gmail.com", "jimmy@jimmycuadra.com"]
6
6
  spec.description = %q{Lita adapter for Slack.}
@@ -17,10 +17,11 @@ Gem::Specification.new do |spec|
17
17
  spec.add_runtime_dependency "eventmachine"
18
18
  spec.add_runtime_dependency "faraday"
19
19
  spec.add_runtime_dependency "faye-websocket", ">= 0.8.0"
20
- spec.add_runtime_dependency "lita", ">= 4.4.2"
20
+ spec.add_runtime_dependency "lita", ">= 4.6.0"
21
21
  spec.add_runtime_dependency "multi_json"
22
22
 
23
23
  spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "pry-byebug"
24
25
  spec.add_development_dependency "rack-test"
25
26
  spec.add_development_dependency "rake"
26
27
  spec.add_development_dependency "rspec", ">= 3.0.0"
@@ -66,6 +66,119 @@ describe Lita::Adapters::Slack::API do
66
66
  end
67
67
  end
68
68
 
69
+ describe "#send_attachments" do
70
+ let(:attachment) do
71
+ Lita::Adapters::Slack::Attachment.new(attachment_text)
72
+ end
73
+ let(:attachment_text) { "attachment text" }
74
+ let(:attachment_hash) do
75
+ {
76
+ fallback: fallback_text,
77
+ text: attachment_text,
78
+ }
79
+ end
80
+ let(:fallback_text) { attachment_text }
81
+ let(:http_response) { MultiJson.dump({ ok: true }) }
82
+ let(:room) { Lita::Room.new("C1234567890") }
83
+ let(:stubs) do
84
+ Faraday::Adapter::Test::Stubs.new do |stub|
85
+ stub.post(
86
+ "https://slack.com/api/chat.postMessage",
87
+ token: token,
88
+ as_user: true,
89
+ channel: room.id,
90
+ attachments: MultiJson.dump([attachment_hash]),
91
+ ) do
92
+ [http_status, {}, http_response]
93
+ end
94
+ end
95
+ end
96
+
97
+ context "with a simple text attachment" do
98
+ it "sends the attachment" do
99
+ response = subject.send_attachments(room, [attachment])
100
+
101
+ expect(response['ok']).to be(true)
102
+ end
103
+ end
104
+
105
+ context "with a different fallback message" do
106
+ let(:attachment) do
107
+ Lita::Adapters::Slack::Attachment.new(attachment_text, fallback: fallback_text)
108
+ end
109
+ let(:fallback_text) { "fallback text" }
110
+
111
+ it "sends the attachment" do
112
+ response = subject.send_attachments(room, [attachment])
113
+
114
+ expect(response['ok']).to be(true)
115
+ end
116
+ end
117
+
118
+ context "with all the valid options" do
119
+ let(:attachment) do
120
+ Lita::Adapters::Slack::Attachment.new(attachment_text, common_hash_data)
121
+ end
122
+ let(:attachment_hash) do
123
+ common_hash_data.merge(fallback: attachment_text, text: attachment_text)
124
+ end
125
+ let(:common_hash_data) do
126
+ {
127
+ author_icon: "http://example.com/author.jpg",
128
+ author_link: "http://example.com/author",
129
+ author_name: "author name",
130
+ color: "#36a64f",
131
+ fields: [{
132
+ title: "priority",
133
+ value: "high",
134
+ short: true,
135
+ }, {
136
+ title: "super long field title",
137
+ value: "super long field value",
138
+ short: false,
139
+ }],
140
+ image_url: "http://example.com/image.jpg",
141
+ pretext: "pretext",
142
+ thumb_url: "http://example.com/thumb.jpg",
143
+ title: "title",
144
+ title_link: "http://example.com/title",
145
+ }
146
+ end
147
+
148
+ it "sends the attachment" do
149
+ response = subject.send_attachments(room, [attachment])
150
+
151
+ expect(response['ok']).to be(true)
152
+ end
153
+ end
154
+
155
+ context "with a Slack error" do
156
+ let(:http_response) do
157
+ MultiJson.dump({
158
+ ok: false,
159
+ error: 'invalid_auth'
160
+ })
161
+ end
162
+
163
+ it "raises a RuntimeError" do
164
+ expect { subject.send_attachments(room, [attachment]) }.to raise_error(
165
+ "Slack API call to chat.postMessage returned an error: invalid_auth."
166
+ )
167
+ end
168
+ end
169
+
170
+ context "with an HTTP error" do
171
+ let(:http_status) { 422 }
172
+ let(:http_response) { '' }
173
+
174
+ it "raises a RuntimeError" do
175
+ expect { subject.send_attachments(room, [attachment]) }.to raise_error(
176
+ "Slack API call to chat.postMessage failed with status code 422."
177
+ )
178
+ end
179
+ end
180
+ end
181
+
69
182
  describe "#set_topic" do
70
183
  let(:channel) { 'C1234567890' }
71
184
  let(:topic) { 'Topic' }
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::Adapters::Slack::ChatService, lita: true do
4
+ subject { described_class.new(adapter.config) }
5
+
6
+ let(:adapter) { Lita::Adapters::Slack.new(robot) }
7
+ let(:robot) { Lita::Robot.new(registry) }
8
+ let(:room) { Lita::Room.new("C2147483705") }
9
+
10
+ before do
11
+ registry.register_adapter(:slack, Lita::Adapters::Slack)
12
+ end
13
+
14
+ describe "#send_attachments" do
15
+ let(:attachment) { Lita::Adapters::Slack::Attachment.new("attachment text") }
16
+
17
+ it "can send a simple text attachment" do
18
+ expect(subject.api).to receive(:send_attachments).with(room, [attachment])
19
+
20
+ subject.send_attachments(room, attachment)
21
+ end
22
+
23
+ it "is aliased as send_attachment" do
24
+ expect(subject.api).to receive(:send_attachments).with(room, [attachment])
25
+
26
+ subject.send_attachment(room, attachment)
27
+ end
28
+ end
29
+ end
@@ -193,7 +193,7 @@ describe Lita::Adapters::Slack::MessageHandler, lita: true do
193
193
 
194
194
  end
195
195
 
196
- context "changes <@123> links to @name" do
196
+ context "changes <@123> links to @label" do
197
197
  let(:data) do
198
198
  {
199
199
  "type" => "message",
@@ -204,7 +204,7 @@ describe Lita::Adapters::Slack::MessageHandler, lita: true do
204
204
  it "removes formatting" do
205
205
  expect(Lita::Message).to receive(:new).with(
206
206
  robot,
207
- "foo @name bar",
207
+ "foo @label bar",
208
208
  source
209
209
  ).and_return(message)
210
210
 
@@ -21,6 +21,12 @@ describe Lita::Adapters::Slack, lita: true do
21
21
  expect(Lita.adapters[:slack]).to eql(described_class)
22
22
  end
23
23
 
24
+ describe "#chat_service" do
25
+ it "returns an object with Slack-specific methods" do
26
+ expect(subject.chat_service).to be_an_instance_of(described_class::ChatService)
27
+ end
28
+ end
29
+
24
30
  describe "#run" do
25
31
  it "starts the RTM connection" do
26
32
  expect(rtm_connection).to receive(:run)
@@ -9,6 +9,8 @@ SimpleCov.start { add_filter "/spec/" }
9
9
  require "lita-slack"
10
10
  require "lita/rspec"
11
11
 
12
+ require "pry"
13
+
12
14
  Lita.version_3_compatibility_mode = false
13
15
 
14
16
  RSpec.configure do |config|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lita-slack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken J.
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-06-12 00:00:00.000000000 Z
12
+ date: 2015-08-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -59,14 +59,14 @@ dependencies:
59
59
  requirements:
60
60
  - - ">="
61
61
  - !ruby/object:Gem::Version
62
- version: 4.4.2
62
+ version: 4.6.0
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: 4.4.2
69
+ version: 4.6.0
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: multi_json
72
72
  requirement: !ruby/object:Gem::Requirement
@@ -95,6 +95,20 @@ dependencies:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
97
  version: '1.3'
98
+ - !ruby/object:Gem::Dependency
99
+ name: pry-byebug
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
98
112
  - !ruby/object:Gem::Dependency
99
113
  name: rack-test
100
114
  requirement: !ruby/object:Gem::Requirement
@@ -182,6 +196,8 @@ files:
182
196
  - lib/lita-slack.rb
183
197
  - lib/lita/adapters/slack.rb
184
198
  - lib/lita/adapters/slack/api.rb
199
+ - lib/lita/adapters/slack/attachment.rb
200
+ - lib/lita/adapters/slack/chat_service.rb
185
201
  - lib/lita/adapters/slack/event_loop.rb
186
202
  - lib/lita/adapters/slack/im_mapping.rb
187
203
  - lib/lita/adapters/slack/message_handler.rb
@@ -195,6 +211,7 @@ files:
195
211
  - lita-slack.gemspec
196
212
  - locales/en.yml
197
213
  - spec/lita/adapters/slack/api_spec.rb
214
+ - spec/lita/adapters/slack/chat_service_spec.rb
198
215
  - spec/lita/adapters/slack/event_loop_spec.rb
199
216
  - spec/lita/adapters/slack/im_mapping_spec.rb
200
217
  - spec/lita/adapters/slack/message_handler_spec.rb
@@ -227,12 +244,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
227
244
  version: '0'
228
245
  requirements: []
229
246
  rubyforge_project:
230
- rubygems_version: 2.4.5
247
+ rubygems_version: 2.4.5.1
231
248
  signing_key:
232
249
  specification_version: 4
233
250
  summary: Lita adapter for Slack.
234
251
  test_files:
235
252
  - spec/lita/adapters/slack/api_spec.rb
253
+ - spec/lita/adapters/slack/chat_service_spec.rb
236
254
  - spec/lita/adapters/slack/event_loop_spec.rb
237
255
  - spec/lita/adapters/slack/im_mapping_spec.rb
238
256
  - spec/lita/adapters/slack/message_handler_spec.rb