slappy 0.4.0 → 0.5.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: 8e79a1760b63ef1b9dc0b47ddc653346f56d972f
4
- data.tar.gz: 081b83f1f491f9173a1fd25f085c42faed243013
3
+ metadata.gz: 279a9dc258db912d4e7ed619595d66553ea75d69
4
+ data.tar.gz: 1937de721354dba64d166128b34bad6b24726723
5
5
  SHA512:
6
- metadata.gz: c5b60c4a6050e4df1e15f5f0d8ddd3a544edbf69669c18148dd505e05ddd152041dd14acfd662db472d73338ca32347a54cd409cdfee0e232a72374f0c78ed6b
7
- data.tar.gz: af1e4362d1387b85cc69e7492ed88b9b2f0f0a8e5bae0fd8eb042c2762742b597ad90c1cc4f3fddfb01db993d293742ed575173d3eddc9af1a2da81124edfecd
6
+ metadata.gz: 0ce87466b06fccd78a49e18e007dab3db1ec345e9c844437a05df2bc831a86ece70ebcb55cf00906a5312c7aa4b07a951216fc270500145066c819ce4388712c
7
+ data.tar.gz: 2b85a23ac6d034c6c9dd623d6d61da941466ea652753ba9cdcd816cea73b78a903a0263f1dd4aec2da5bf7c89d44c7c593ae50030c85a802c14c35288a33411e
data/README.md CHANGED
@@ -112,48 +112,104 @@ robot.username - default: 'slappy'
112
112
  robot.icon_emoji - default: nil
113
113
  robot.channel - default: '#general'
114
114
  robot.icon_url - default: nil
115
+ robot.as_user - default: false
115
116
  ```
116
117
 
117
118
  ### Basic Usage
118
119
 
119
- If you not want execute `slappy start` command, written by (require `'slappy/dsl'` use DSL):
120
-
121
120
  ```ruby
122
- require 'slappy'
123
-
124
121
  # called when start up
125
- Slappy.hello do
126
- Slappy.logger.info 'successfly connected'
122
+ hello do
123
+ logger.info 'successfly connected'
127
124
  end
125
+ ```
126
+
127
+ #### Send and Receive Message
128
128
 
129
+ ```ruby
129
130
  # called when match message
130
- Slappy.hear 'foo' do
131
- Slappy.logger.info 'foo'
131
+ hear 'foo' do
132
+ logger.info 'foo'
132
133
  end
133
134
 
134
135
  # use regexp in string literal
135
- Slappy.hear 'bar (.*)' do |event|
136
- Slappy.logger.info event.matches[1] #=> Event#matches return MatchData object
136
+ hear 'bar (.*)' do |event|
137
+ logger.info event.matches[1] #=> Event#matches return MatchData object
137
138
  end
138
139
 
139
140
  # event object is slack event JSON (convert to Hashie::Mash)
140
- Slappy.hear '^bar (.*)' do |event|
141
- Slappy.logger.info event.channel #=> channel id
142
- Slappy.say 'slappy!', channel: event.channel #=> to received message channel
143
- Slappy.say 'slappy!', channel: '#general'
144
- Slappy.say 'slappy!', username: 'slappy!', icon_emoji: ':slappy:'
141
+ hear '^bar (.*)' do |event|
142
+ say 'slappy!', channel: event.channel #=> to received channel object
143
+ say 'slappy!', channel: '#general' #=> send to public channel
144
+ say 'slappy!', channel: 'private-room' #=> send to private group
145
+ say 'slappy!', username: 'slappy!', icon_emoji: ':slappy:' #=> change config
145
146
  end
146
147
 
147
148
  # use regexp literal
148
- Slappy.hear /^foobar/ do
149
- Slappy.logger.info 'slappppy!'
149
+ hear(/^foobar/) do
150
+ logger.info 'slappppy!'
151
+ end
152
+ ```
153
+
154
+ #### Monitoring Subtypes Event
155
+
156
+ ```ruby
157
+ monitor 'channel_joined' do |event|
158
+ say "Welcome to #{event.name}!", channel: event.channel
150
159
  end
151
160
 
152
- Slappy.start #=> Start slappy process
161
+ monitor 'team_join' do |event|
162
+ say "Welcome to this team!", channel: "#general"
163
+ end
164
+ ```
165
+
166
+ #### Schedule Event
167
+
168
+ ```ruby
169
+ schedule '* * * * *' do
170
+ logger.info 'Slappy alive...' #=> Repeat every minutes.
171
+ end
172
+
173
+ ```
174
+
175
+ ### DSL Methods
176
+
177
+ |method|when execute callback|
178
+ |:---:|:---|
179
+ |hello|start up|
180
+ |hear|message (match pattern)|
181
+ |monitor|[Slack RTM event](https://api.slack.com/rtm)|
182
+ |schedule|specify time ([Syntax is here](https://github.com/r7kamura/chrono)) - Thanks to Chrono!|
183
+
184
+ ### In your Application
185
+
186
+ If you not want execute `slappy start` command, written by (require `'slappy/dsl'` use DSL):
187
+
188
+ ```
189
+ require 'slappy'
190
+
191
+ Slappy.hello do
192
+ # In your code..
193
+ end
194
+
195
+ Slappy.say 'message to slack'
196
+
197
+ Slappy.start #=> Start WebSocket connection
153
198
  ```
154
199
 
155
200
  ## Release Note
156
201
 
202
+ - v0.5.0
203
+ - Support Schedule
204
+ - Support Slack RMT Event
205
+ - Support private group
206
+ - Support as_user option
207
+ - Introduce SlackAPI objects
208
+ - Group
209
+ - Channel
210
+ - Direct
211
+ - User
212
+
157
213
  - v0.4.0
158
214
  - Support logger
159
215
  - Support load lib directory
data/lib/slappy/client.rb CHANGED
@@ -27,13 +27,22 @@ module Slappy
27
27
 
28
28
  def hear(pattern, &block)
29
29
  @callbacks[:message] ||= []
30
- @callbacks[:message].push Listener.new(pattern, block)
30
+ @callbacks[:message].push Listener::TextListener.new(pattern, block)
31
+ end
32
+
33
+ def monitor(subtype, &block)
34
+ @callbacks[:message] ||= []
35
+ @callbacks[:message].push Listener::SubtypeListener.new(subtype, block)
31
36
  end
32
37
 
33
38
  def say(text, options = {})
34
39
  options[:text] = text
35
- params = merge_send_params options
36
- Slack.chat_postMessage params
40
+ Messanger.new(options).message
41
+ end
42
+
43
+ def schedule(schedule, options = {}, &block)
44
+ @schedule ||= Schedule.new
45
+ @schedule.register schedule, options, &block
37
46
  end
38
47
 
39
48
  private
@@ -53,7 +62,7 @@ module Slappy
53
62
  when :hello
54
63
  listener.call
55
64
  when :message
56
- event = Event.new(data, listener.pattern)
65
+ event = Event.new(data)
57
66
  listener.call(event)
58
67
  end
59
68
  end
@@ -63,10 +72,5 @@ module Slappy
63
72
  def config
64
73
  Slappy.configuration
65
74
  end
66
-
67
- def merge_send_params(options)
68
- default = config.send_params
69
- default.merge options
70
- end
71
75
  end
72
76
  end
@@ -1,7 +1,11 @@
1
1
  module Slappy
2
2
  class Configuration
3
3
  class Robot
4
- attr_accessor :botname, :username, :channel, :icon_emoji, :icon_url
4
+ attr_accessor :botname, :username, :channel, :icon_emoji, :icon_url, :as_user
5
+
6
+ def as_user
7
+ @as_user || false
8
+ end
5
9
 
6
10
  def botname
7
11
  @botname || username
@@ -43,7 +43,8 @@ module Slappy
43
43
  username: robot.username,
44
44
  icon_emoji: robot.icon_emoji,
45
45
  channel: robot.channel,
46
- icon_url: robot.icon_url
46
+ icon_url: robot.icon_url,
47
+ as_user: robot.as_user
47
48
  }
48
49
  end
49
50
  end
data/lib/slappy/dsl.rb CHANGED
@@ -2,7 +2,7 @@ module Slappy
2
2
  module DSL
3
3
  extend Forwardable
4
4
 
5
- def_delegators :Slappy, :hello, :hear, :say, :start, :logger
5
+ def_delegators :Slappy, :hello, :hear, :say, :start, :logger, :schedule, :monitor
6
6
  end
7
7
  end
8
8
 
data/lib/slappy/event.rb CHANGED
@@ -2,17 +2,30 @@ module Slappy
2
2
  class Event
3
3
  extend Forwardable
4
4
 
5
- attr_reader :matches
5
+ attr_accessor :matches
6
6
 
7
7
  def_delegators :@data, :method_missing, :respond_to_missing?
8
8
 
9
- def initialize(data, pattern)
9
+ def initialize(data)
10
10
  @data = Hashie::Mash.new data
11
- @matches = text.match pattern
12
11
  end
13
12
 
14
13
  def text
15
14
  @data['text'].to_s
16
15
  end
16
+
17
+ def channel
18
+ SlackAPI::Channel.find(id: @data['channel']) ||
19
+ SlackAPI::Group.find(id: @data['channel']) ||
20
+ SlackAPI::Direct.find(id: @data['channel'])
21
+ end
22
+
23
+ def user
24
+ SlackAPI::User.find(id: @data['user'])
25
+ end
26
+
27
+ def ts
28
+ Time.at(@data['ts'].to_f)
29
+ end
17
30
  end
18
31
  end
@@ -1,19 +1,9 @@
1
- module Slappy
2
- class Listener
3
- def initialize(pattern, callback)
4
- pattern = /#{pattern}/ if pattern.is_a? String
5
- @regexp = pattern
6
- @callback = callback
7
- end
8
-
9
- def call(event)
10
- return unless Time.at(event.ts.to_f) > Slappy.client.start_time
11
- return unless event.text.match @regexp
12
- @callback.call(event)
13
- end
1
+ require 'slappy/listeners/concerns/listenable'
2
+ require 'slappy/listeners/base'
3
+ require 'slappy/listeners/text_listener'
4
+ require 'slappy/listeners/subtype_listener'
14
5
 
15
- def pattern
16
- @regexp
17
- end
6
+ module Slappy
7
+ module Listener
18
8
  end
19
9
  end
@@ -0,0 +1,7 @@
1
+ module Slappy
2
+ module Listener
3
+ class Base
4
+ include Listenable
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,36 @@
1
+ module Slappy
2
+ module Listener
3
+ module Listenable
4
+ include ActiveSupport::Concern
5
+
6
+ attr_reader :pattern
7
+
8
+ def initialize(target, callback)
9
+ @pattern = target
10
+ @callback = callback
11
+ end
12
+
13
+ def call(event)
14
+ return unless time_valid?(event)
15
+
16
+ target = event.send(target_element)
17
+ return unless target
18
+
19
+ event.matches = target.match pattern
20
+ return unless event.matches
21
+
22
+ @callback.call(event)
23
+ end
24
+
25
+ def time_valid?(event)
26
+ event.ts > Slappy.client.start_time
27
+ end
28
+
29
+ private
30
+
31
+ def target_element
32
+ self.class.name.split('::').last.gsub(/Listener$/, '').underscore.to_sym
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,6 @@
1
+ module Slappy
2
+ module Listener
3
+ class SubtypeListener < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module Slappy
2
+ module Listener
3
+ class TextListener < Base
4
+ def pattern
5
+ return /#{@pattern}/ if @pattern.instance_of? String
6
+ @pattern
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,44 @@
1
+ module Slappy
2
+ class Messanger
3
+ class MissingChannelException < StandardError; end
4
+
5
+ CHANNEL_APIS = [SlackAPI::Channel, SlackAPI::Group, SlackAPI::Direct]
6
+
7
+ def initialize(options)
8
+ @destination = {}
9
+ @destination = options[:channel]
10
+ options.delete :channel
11
+ @options = options
12
+ end
13
+
14
+ def message
15
+ options = merge_params(@options)
16
+
17
+ if @destination.is_a? SlackAPI::Base
18
+ id = @destination.id
19
+ else
20
+ instance = nil
21
+ CHANNEL_APIS.each do |klass|
22
+ instance = klass.find(name: @destination) || klass.find(id: @destination)
23
+ break unless instance.nil?
24
+ end
25
+ fail MissingChannelException.new, "channel / #{@destination} is not found" if instance.nil?
26
+ id = instance.id
27
+ end
28
+
29
+ options[:channel] = id
30
+ Slack.chat_postMessage options
31
+ end
32
+
33
+ private
34
+
35
+ def config
36
+ Slappy.configuration
37
+ end
38
+
39
+ def merge_params(options)
40
+ default = config.send_params
41
+ default.merge options
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,39 @@
1
+ require 'securerandom'
2
+
3
+ module Slappy
4
+ class Schedule
5
+ class OverScheduleError < StandardError; end
6
+ class InvalidFormatError < StandardError; end
7
+
8
+ DEFAULT_MAX_THREAD = 1000
9
+
10
+ def register(schedule, options = {}, &block)
11
+ id = options[:id] || generate_id
12
+ schedule_list[id] = Thread.new { Chrono::Trigger.new(schedule) { block.call }.run }
13
+ Slappy.logger.try(:debug, "Schedule registerd to #{schedule}")
14
+ id
15
+ end
16
+
17
+ def remove(id)
18
+ registered = @schedule_list.include? id
19
+ if registered
20
+ @schedule_list[id].kill
21
+ @schedule_list.delete id
22
+ end
23
+ registered
24
+ end
25
+
26
+ private
27
+
28
+ def schedule_list
29
+ @schedule_list ||= {}
30
+ end
31
+
32
+ def generate_id
33
+ figure = Math.log10(DEFAULT_MAX_THREAD) + 1
34
+ id = format("%0#{figure}d", SecureRandom.random_number(DEFAULT_MAX_THREAD))
35
+ id = generate_id if schedule_list.include? id
36
+ id
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,7 @@
1
+ module Slappy
2
+ module SlackAPI
3
+ class Base
4
+ include Findable
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module Slappy
2
+ module SlackAPI
3
+ class Channel < Base
4
+ self.monitor_event = 'channel_created'
5
+
6
+ def name
7
+ '#' + @data.name
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,57 @@
1
+ module Slappy
2
+ module SlackAPI
3
+ module Findable
4
+ extend ActiveSupport::Concern
5
+ extend Forwardable
6
+
7
+ def_delegators :@data, :method_missing, :respond_to?
8
+
9
+ def initialize(data)
10
+ @data = Hashie::Mash.new data
11
+ end
12
+
13
+ module ClassMethods
14
+ attr_reader :list_name, :api_name, :monitor_event
15
+
16
+ def api_name=(api_name)
17
+ @api_name = api_name
18
+ end
19
+
20
+ def list_name=(list_name)
21
+ @list_name = list_name
22
+ end
23
+
24
+ def monitor_event=(target)
25
+ target = [target] unless target.instance_of? Array
26
+ @monitor_event = target
27
+ end
28
+
29
+ def list(options = {})
30
+ @monitor_event.each do |event|
31
+ Slappy.monitor event do
32
+ @list = nil
33
+ end
34
+ end
35
+
36
+ unless @list
37
+ api_name = self.api_name || name.split('::').last.downcase + 's'
38
+ list_name = self.list_name || api_name
39
+ method_name = "#{api_name}_list"
40
+
41
+ @list = Slack.send(method_name, options)[list_name].map { |data| new(data) }
42
+ end
43
+ @list
44
+ end
45
+
46
+ def find(arg)
47
+ return find_by_keyword(arg) if arg.instance_of? Hash
48
+ find id: arg
49
+ end
50
+
51
+ def find_by_keyword(hash)
52
+ hash.map { |key, value| list.find { |obj| obj.send(key) == value } }.first
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,9 @@
1
+ module Slappy
2
+ module SlackAPI
3
+ class Direct < Base
4
+ self.api_name = 'im'
5
+ self.list_name = 'ims'
6
+ self.monitor_event = 'im_open'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module Slappy
2
+ module SlackAPI
3
+ class Group < Base
4
+ self.monitor_event = %w(group_joined group_open)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ module Slappy
2
+ module SlackAPI
3
+ class User < Base
4
+ self.list_name = 'members'
5
+ self.monitor_event = 'team_join'
6
+
7
+ def name
8
+ '@' + @data.name
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module Slappy
2
- VERSION = '0.4.0'
2
+ VERSION = '0.5.0'
3
3
  end
data/lib/slappy.rb CHANGED
@@ -1,5 +1,8 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+ require 'active_support/concern'
4
+ require 'chrono'
1
5
  require 'forwardable'
2
- require 'active_support/core_ext/string/inflections'
3
6
  require 'hashie'
4
7
  require 'slack'
5
8
  require 'termcolor'
@@ -11,7 +14,7 @@ module Slappy
11
14
  extend Forwardable
12
15
 
13
16
  def_delegators :configuration, :logger
14
- def_delegators :client, :start, :hello, :hear, :say
17
+ def_delegators :client, :start, :hello, :hear, :say, :schedule, :monitor
15
18
 
16
19
  def configure
17
20
  @configuration = Configuration.new
@@ -31,6 +34,12 @@ module Slappy
31
34
  end
32
35
  end
33
36
 
37
+ require 'slappy/slack_api/concerns/findable'
38
+ require 'slappy/slack_api/base'
39
+ require 'slappy/slack_api/channel'
40
+ require 'slappy/slack_api/direct'
41
+ require 'slappy/slack_api/group'
42
+ require 'slappy/slack_api/user'
34
43
  require 'slappy/cli'
35
44
  require 'slappy/client'
36
45
  require 'slappy/configuration'
@@ -39,4 +48,6 @@ require 'slappy/commands/generator.rb'
39
48
  require 'slappy/commands/run.rb'
40
49
  require 'slappy/event'
41
50
  require 'slappy/listener'
51
+ require 'slappy/messanger'
52
+ require 'slappy/schedule'
42
53
  require 'slappy/version'
data/slappy.gemspec CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency 'thor'
24
24
  spec.add_dependency "activesupport"
25
25
  spec.add_dependency "termcolor"
26
+ spec.add_dependency "chrono"
26
27
  spec.add_development_dependency "bundler", "~> 1.10"
27
28
  spec.add_development_dependency "rake", "~> 10.0"
28
29
  spec.add_development_dependency "rspec"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slappy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - wakaba260
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-12 00:00:00.000000000 Z
11
+ date: 2015-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: slack-api
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: chrono
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: bundler
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -214,7 +228,6 @@ executables:
214
228
  extensions: []
215
229
  extra_rdoc_files: []
216
230
  files:
217
- - ".env.sample"
218
231
  - ".gitignore"
219
232
  - ".hound.yml"
220
233
  - ".rspec"
@@ -237,6 +250,18 @@ files:
237
250
  - lib/slappy/dsl.rb
238
251
  - lib/slappy/event.rb
239
252
  - lib/slappy/listener.rb
253
+ - lib/slappy/listeners/base.rb
254
+ - lib/slappy/listeners/concerns/listenable.rb
255
+ - lib/slappy/listeners/subtype_listener.rb
256
+ - lib/slappy/listeners/text_listener.rb
257
+ - lib/slappy/messanger.rb
258
+ - lib/slappy/schedule.rb
259
+ - lib/slappy/slack_api/base.rb
260
+ - lib/slappy/slack_api/channel.rb
261
+ - lib/slappy/slack_api/concerns/findable.rb
262
+ - lib/slappy/slack_api/direct.rb
263
+ - lib/slappy/slack_api/group.rb
264
+ - lib/slappy/slack_api/user.rb
240
265
  - lib/slappy/version.rb
241
266
  - slappy.gemspec
242
267
  - templates/example.rb
@@ -261,7 +286,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
261
286
  version: '0'
262
287
  requirements: []
263
288
  rubyforge_project:
264
- rubygems_version: 2.4.8
289
+ rubygems_version: 2.4.5.1
265
290
  signing_key:
266
291
  specification_version: 4
267
292
  summary: Simple Slack Bot Framework
data/.env.sample DELETED
@@ -1 +0,0 @@
1
- SLACK_TOKEN=