slack-rtm-receiver 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +60 -0
- data/lib/slack-rtm-receiver.rb +11 -0
- data/lib/slack-rtm-receiver/event-handler.rb +48 -0
- data/lib/slack-rtm-receiver/logger.rb +24 -0
- data/lib/slack-rtm-receiver/reactor.rb +32 -0
- data/lib/slack-rtm-receiver/session.rb +199 -0
- data/lib/slack-rtm-receiver/starter.rb +76 -0
- data/lib/slack-rtm-receiver/version.rb +5 -0
- data/slack-rtm-receiver.gemspec +21 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1821e8e1626538c67c4d4decf64cd3535011a2af
|
4
|
+
data.tar.gz: ab3b8e9761278e7988ecc4455d798f1522fa22c9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 49680d9a6a7fd5221a7f5d5f904c0c401c65b719c018de616742cbff52dc6899e2a573f7b31bedbff5653e85d12d685aa68b5d6dc8ef59ca2a2b2c96ae0c27eb
|
7
|
+
data.tar.gz: c4c5d3750d586452ef925e7cd0abaf5edb75934d8c8c2aaa57a441db00caaad2a1d2b2712e688ced049167f4e2a4746fa4aae901752a27b563c636e99441d7f3
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Ken J.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# slack-rtm-receiver
|
2
|
+
|
3
|
+
A Ruby gem. It connects to Slack Real Time Messaging API to receive events. Runs on EventMachine.
|
4
|
+
|
5
|
+
## Requirements
|
6
|
+
|
7
|
+
- Ruby 2.0.0 <=
|
8
|
+
- eventmachine 1.0
|
9
|
+
- em-http-request 1.1
|
10
|
+
- faye-websocket 0.8
|
11
|
+
|
12
|
+
## Getting Started
|
13
|
+
|
14
|
+
### Install
|
15
|
+
|
16
|
+
```
|
17
|
+
$ gem install slack-rtm-receiver
|
18
|
+
```
|
19
|
+
|
20
|
+
### Use
|
21
|
+
|
22
|
+
```
|
23
|
+
require 'slack-rtm-receiver'
|
24
|
+
```
|
25
|
+
|
26
|
+
Create an object to respond to received events. You can subclass **EventHandler**.
|
27
|
+
```
|
28
|
+
class MyHandler < SlackRTMReceiver::EventHandler
|
29
|
+
def process_event(event, session)
|
30
|
+
if event[:text] == 'hi'
|
31
|
+
res_event = {
|
32
|
+
type: 'message',
|
33
|
+
channel: event[:channel],
|
34
|
+
text: 'Hi!'
|
35
|
+
}
|
36
|
+
session.send_event(res_event)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
SlackRTMReceiver.add_event_handler(MyHandler.new)
|
41
|
+
```
|
42
|
+
Or, you can pass a block. The following works the same as above.
|
43
|
+
```
|
44
|
+
SlackRTMReceiver::EventHandler.add_type('message') do |event, session|
|
45
|
+
if event[:text] == 'hi'
|
46
|
+
res_event = {
|
47
|
+
type: 'message',
|
48
|
+
channel: event[:channel],
|
49
|
+
text: 'Hi!'
|
50
|
+
}
|
51
|
+
session.send_event(res_event)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
Start the reactor to connect to Slack.
|
57
|
+
```
|
58
|
+
opts = {token: 'xoxb-1234abcd5678efgh'}
|
59
|
+
SlackRTMReceiver::Reactor.run(opts)
|
60
|
+
```
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'slack-rtm-receiver/event-handler'
|
2
|
+
require 'slack-rtm-receiver/logger'
|
3
|
+
require 'slack-rtm-receiver/reactor'
|
4
|
+
require 'slack-rtm-receiver/session'
|
5
|
+
require 'slack-rtm-receiver/starter'
|
6
|
+
require 'slack-rtm-receiver/version'
|
7
|
+
|
8
|
+
|
9
|
+
module SlackRTMReceiver
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module SlackRTMReceiver
|
2
|
+
|
3
|
+
def self.event_handlers=(handlers)
|
4
|
+
@event_handlers = handlers
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.event_handlers
|
8
|
+
@event_handlers ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.add_event_handler(handler)
|
12
|
+
@event_handlers ||= []
|
13
|
+
@event_handlers << handler
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create objects to handle events:
|
17
|
+
# - subclass EventHandler, or
|
18
|
+
# - just create an instance and pass a block
|
19
|
+
class EventHandler
|
20
|
+
|
21
|
+
# Create and register a handler object by passing a block
|
22
|
+
# @param type [String] event type
|
23
|
+
def self.add_type(type, &block)
|
24
|
+
handler = new(type, &block)
|
25
|
+
SlackRTMReceiver.add_event_handler(handler)
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :type
|
29
|
+
|
30
|
+
# Create a new handler instance
|
31
|
+
# @param type [String] event type
|
32
|
+
def initialize(type = 'message', &block)
|
33
|
+
@type = type
|
34
|
+
@block = block if block_given?
|
35
|
+
end
|
36
|
+
|
37
|
+
# Callback method; called by SlackRTMReceiver::Session when event is received
|
38
|
+
# @param [Hash] event data
|
39
|
+
# @param [Object] caller object
|
40
|
+
def process_event(event, session)
|
41
|
+
logger = session.logger
|
42
|
+
logger.debug "#{self.class.name} running..."
|
43
|
+
@block.call(event, session) if @block
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
|
4
|
+
module SlackRTMReceiver
|
5
|
+
|
6
|
+
def self.logger=(logger)
|
7
|
+
@logger = logger
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.logger
|
11
|
+
@logger ||= NullLogger.new()
|
12
|
+
end
|
13
|
+
|
14
|
+
class NullLogger < Logger
|
15
|
+
|
16
|
+
def initialize(*args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def add(*args, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
|
3
|
+
|
4
|
+
module SlackRTMReceiver
|
5
|
+
|
6
|
+
class Reactor
|
7
|
+
|
8
|
+
# Start reactor
|
9
|
+
# @param opts [Hash] options for Slack web API rtm.start
|
10
|
+
def self.run(opts)
|
11
|
+
logger = SlackRTMReceiver.logger
|
12
|
+
logger.info "SlackRTMReceiver ver. #{Version} loaded, Reactor starting..."
|
13
|
+
EM.run do
|
14
|
+
session = Session.new
|
15
|
+
starter = Starter.start(session, opts)
|
16
|
+
|
17
|
+
# life check
|
18
|
+
EM.add_periodic_timer(15) do
|
19
|
+
session.alive? ? session.ping_if_idle : starter.start(session)
|
20
|
+
end
|
21
|
+
|
22
|
+
# statistics check
|
23
|
+
EM.add_periodic_timer(3600) do
|
24
|
+
session.stats({log: true}) if session.alive?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
logger.warn 'Reactor stopped'
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'faye/websocket'
|
2
|
+
|
3
|
+
|
4
|
+
module SlackRTMReceiver
|
5
|
+
|
6
|
+
# Websocket client for the RTM session
|
7
|
+
class Session
|
8
|
+
|
9
|
+
attr_reader :logger
|
10
|
+
attr_reader :websocket
|
11
|
+
alias_method :ws, :websocket
|
12
|
+
attr_reader :last_timestamp
|
13
|
+
alias_method :ts, :last_timestamp
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@logger = SlackRTMReceiver.logger
|
17
|
+
logger.debug 'Initializing Session...'
|
18
|
+
@websocket = nil
|
19
|
+
@last_timestamp = nil
|
20
|
+
@ping = nil
|
21
|
+
@stats = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
# Start RTM websocket session
|
25
|
+
# @param url [String] websocket URL
|
26
|
+
# @return [Boolean] false if a session is already up
|
27
|
+
def start(url)
|
28
|
+
return false if ws
|
29
|
+
logger.debug "Connecting to websocket...\n URL: #{url}"
|
30
|
+
opts = {ping: 60}
|
31
|
+
@websocket = Faye::WebSocket::Client.new(url, nil, opts)
|
32
|
+
|
33
|
+
ws.on :open do
|
34
|
+
logger.debug 'Websocket opened'
|
35
|
+
touch_ts
|
36
|
+
end
|
37
|
+
|
38
|
+
ws.on :message do |ws_event|
|
39
|
+
touch_ts
|
40
|
+
event = JSON.parse(ws_event.data, {symbolize_names: true})
|
41
|
+
case event[:type]
|
42
|
+
when 'hello'
|
43
|
+
hello_handler(event)
|
44
|
+
when 'pong'
|
45
|
+
pong_handler(event)
|
46
|
+
else
|
47
|
+
run_event_handlers(event)
|
48
|
+
end
|
49
|
+
@stats[:events_received] ||= 0
|
50
|
+
@stats[:events_received] += 1
|
51
|
+
end
|
52
|
+
|
53
|
+
ws.on :close do |ws_event|
|
54
|
+
logger.warn 'RTM session closed'
|
55
|
+
cleanup
|
56
|
+
end
|
57
|
+
|
58
|
+
return true
|
59
|
+
end
|
60
|
+
|
61
|
+
# Send RTM event
|
62
|
+
# @param event [Hash] RTM event; 'id' will be added automatically
|
63
|
+
# @return [Hash] the event that was sent
|
64
|
+
def send_event(event)
|
65
|
+
return nil unless ws
|
66
|
+
event[:id] = new_event_id
|
67
|
+
ws.send(JSON.fast_generate(event))
|
68
|
+
logger.info "Event sent with id: #{event[:id]} type: #{event[:type]}"
|
69
|
+
logger.debug "Sent event: #{event}"
|
70
|
+
return event
|
71
|
+
end
|
72
|
+
|
73
|
+
# True if RTM session is alive
|
74
|
+
def alive?
|
75
|
+
# return true if ws && ts && Time.now - ts < 30
|
76
|
+
return true if ws && ts
|
77
|
+
return false
|
78
|
+
end
|
79
|
+
|
80
|
+
# Idle for how long?
|
81
|
+
# @return [Float] seconds
|
82
|
+
def idle_time
|
83
|
+
return 0 unless alive?
|
84
|
+
return Time.now - ts
|
85
|
+
end
|
86
|
+
|
87
|
+
# Send RTM ping
|
88
|
+
# @param timeout [Fixnum] timeout in seconds
|
89
|
+
# @return [Boolean] true if pinged
|
90
|
+
def ping(timeout = 5)
|
91
|
+
if @ping
|
92
|
+
logger.debug 'RTM ping requested, but another was recently sent. Ignoring...'
|
93
|
+
return false
|
94
|
+
end
|
95
|
+
event = send_event({type: 'ping', time: Time.now.to_f})
|
96
|
+
return false unless event
|
97
|
+
timer = EM::Timer.new(timeout) do
|
98
|
+
logger.warn "RTM ping timed out: threshold #{timeout} sec"
|
99
|
+
close
|
100
|
+
end
|
101
|
+
event[:em_timer] = timer
|
102
|
+
@ping = event
|
103
|
+
@stats[:pings_sent] ||= 0
|
104
|
+
@stats[:pings_sent] += 1
|
105
|
+
return true
|
106
|
+
end
|
107
|
+
|
108
|
+
# Ping if idle for more than set seconds
|
109
|
+
# @param sec [Fixnum] idle time in seconds
|
110
|
+
# @return [Boolean] true if pinged
|
111
|
+
def ping_if_idle(sec = 10)
|
112
|
+
return false if idle_time < sec
|
113
|
+
ping
|
114
|
+
end
|
115
|
+
|
116
|
+
# Return statistics
|
117
|
+
# @param opts [Hash]
|
118
|
+
# @return [Hash]
|
119
|
+
def stats(opts = {})
|
120
|
+
return nil if @stats.empty?
|
121
|
+
secs = Time.now - @stats[:hello_time]
|
122
|
+
secs = secs.to_i
|
123
|
+
days = secs / 86400
|
124
|
+
secs = secs % 86400
|
125
|
+
hours = secs / 3600
|
126
|
+
secs = secs % 3600
|
127
|
+
mins = secs / 60
|
128
|
+
secs = secs % 60
|
129
|
+
if opts[:log]
|
130
|
+
msg = "Statistics since #{@stats[:hello_time]} (#{days} days, #{hours} hrs, #{mins} mins, #{secs} secs)\n"
|
131
|
+
msg << "#{@stats}"
|
132
|
+
logger.info msg
|
133
|
+
end
|
134
|
+
return @stats
|
135
|
+
end
|
136
|
+
|
137
|
+
# Close RTM session
|
138
|
+
def close
|
139
|
+
ws.close if ws
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
# Handle RTM hello
|
145
|
+
def hello_handler(event)
|
146
|
+
@stats[:hello_time] = Time.now
|
147
|
+
logger.info 'Hello received, RTM session established'
|
148
|
+
end
|
149
|
+
|
150
|
+
# Handle RTM pong
|
151
|
+
def pong_handler(event)
|
152
|
+
@stats[:pongs_received] ||= 0
|
153
|
+
@stats[:pongs_received] += 1
|
154
|
+
if @ping.nil? || @ping[:id] != event[:reply_to]
|
155
|
+
logger.warn "Unexpected RTM pong received\n Pong: #{event}"
|
156
|
+
return
|
157
|
+
end
|
158
|
+
latency = Time.now.to_f - @ping[:time]
|
159
|
+
logger.info "RTM pong received, ping latency: #{'%.5f' % latency} sec"
|
160
|
+
@ping[:em_timer].cancel
|
161
|
+
@ping = nil
|
162
|
+
@stats[:last_ping_latency] = latency
|
163
|
+
end
|
164
|
+
|
165
|
+
# Run matching handlers
|
166
|
+
def run_event_handlers(event)
|
167
|
+
logger.debug "Received event: #{event}"
|
168
|
+
return unless event[:type]
|
169
|
+
handlers = SlackRTMReceiver.event_handlers
|
170
|
+
handlers.each do |handler|
|
171
|
+
handler.process_event(event, self) if handler.type == event[:type]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Get new RTM event ID
|
176
|
+
def new_event_id
|
177
|
+
@stats[:events_sent] ||= 0
|
178
|
+
return @stats[:events_sent] += 1
|
179
|
+
end
|
180
|
+
|
181
|
+
# Update last timestamp
|
182
|
+
def touch_ts
|
183
|
+
@last_timestamp = Time.now
|
184
|
+
end
|
185
|
+
|
186
|
+
# Reset instance variables
|
187
|
+
def cleanup
|
188
|
+
@hellotime = 0
|
189
|
+
@websocket = nil
|
190
|
+
@last_timestamp = nil
|
191
|
+
@ping = nil
|
192
|
+
stats({log: true})
|
193
|
+
@stats = {}
|
194
|
+
logger.warn 'RTM session closed'
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'em-http'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
|
5
|
+
module SlackRTMReceiver
|
6
|
+
|
7
|
+
# HTTP client to call rtm.start
|
8
|
+
class Starter
|
9
|
+
|
10
|
+
# Create and start a Starter
|
11
|
+
# @param session [SlackRTMReceiver::Session]
|
12
|
+
# @return [SlackRTMReceiver::Starter]
|
13
|
+
def self.start(session, opts = {})
|
14
|
+
starter = self.new(opts)
|
15
|
+
starter.start(session)
|
16
|
+
return starter
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :logger
|
20
|
+
attr_accessor :options
|
21
|
+
|
22
|
+
# @return [Boolean]
|
23
|
+
def started?
|
24
|
+
return true if @is_starting
|
25
|
+
return true if @session && @session.alive?
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param opts [Hash] options for Slack web API rtm.start
|
30
|
+
def initialize(opts)
|
31
|
+
@logger = SlackRTMReceiver.logger
|
32
|
+
logger.debug 'Initializing Starter...'
|
33
|
+
@options = opts
|
34
|
+
@is_starting = false
|
35
|
+
@session = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param session [SlackRTMReceiver::Session]
|
39
|
+
def start(session)
|
40
|
+
if started?
|
41
|
+
logger.debug 'Start requested but already running. Ignoring...'
|
42
|
+
return nil
|
43
|
+
end
|
44
|
+
@is_starting = true
|
45
|
+
@session = session
|
46
|
+
logger.debug 'Starter is calling rtm.start...'
|
47
|
+
baseurl = 'https://slack.com/api/rtm.start'
|
48
|
+
http = EM::HttpRequest.new(baseurl).get(query: @options, redirects: 5)
|
49
|
+
http.callback do
|
50
|
+
callback(http, session)
|
51
|
+
@is_starting = false
|
52
|
+
end
|
53
|
+
http.errback do
|
54
|
+
errback(http)
|
55
|
+
@is_starting = false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# EM::HttpRequest callback handler
|
62
|
+
def callback(http, session)
|
63
|
+
status = http.response_header.status
|
64
|
+
raise "Web API rtm.start failed: received HTTP status code #{status}" unless status == 200
|
65
|
+
logger.info 'Recived rtm.start response'
|
66
|
+
session.start(JSON.parse(http.response)['url'])
|
67
|
+
end
|
68
|
+
|
69
|
+
# EM::HttpRequest error callback handler
|
70
|
+
def errback(http)
|
71
|
+
raise "Web API rtm.start failed: #{http.error}"
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path("../lib", __FILE__))
|
2
|
+
require 'slack-rtm-receiver/version'
|
3
|
+
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'slack-rtm-receiver'
|
7
|
+
s.version = SlackRTMReceiver::Version
|
8
|
+
s.authors = ['Ken J.']
|
9
|
+
s.email = ['kenjij@gmail.com']
|
10
|
+
s.description = %q{Slack RTM receiver}
|
11
|
+
s.summary = %q{Connects to Slack Real Time Messaging API to receive events.}
|
12
|
+
s.homepage = 'https://github.com/kenjij/slack-rtm-receiver'
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split($/)
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
|
18
|
+
s.add_runtime_dependency "eventmachine", "~> 1.0"
|
19
|
+
s.add_runtime_dependency "faye-websocket", "~> 0.8"
|
20
|
+
s.add_runtime_dependency "em-http-request", "~> 1.1"
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: slack-rtm-receiver
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ken J.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: eventmachine
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faye-websocket
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.8'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.8'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: em-http-request
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.1'
|
55
|
+
description: Slack RTM receiver
|
56
|
+
email:
|
57
|
+
- kenjij@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- LICENSE
|
63
|
+
- README.md
|
64
|
+
- lib/slack-rtm-receiver.rb
|
65
|
+
- lib/slack-rtm-receiver/event-handler.rb
|
66
|
+
- lib/slack-rtm-receiver/logger.rb
|
67
|
+
- lib/slack-rtm-receiver/reactor.rb
|
68
|
+
- lib/slack-rtm-receiver/session.rb
|
69
|
+
- lib/slack-rtm-receiver/starter.rb
|
70
|
+
- lib/slack-rtm-receiver/version.rb
|
71
|
+
- slack-rtm-receiver.gemspec
|
72
|
+
homepage: https://github.com/kenjij/slack-rtm-receiver
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.4.3
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Connects to Slack Real Time Messaging API to receive events.
|
96
|
+
test_files: []
|