qbot 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +1 -1
- data/lib/qbot/adapter.rb +2 -2
- data/lib/qbot/adapter/mattermost.rb +40 -37
- data/lib/qbot/adapter/shell.rb +5 -1
- data/lib/qbot/adapter/slack.rb +37 -36
- data/lib/qbot/app.rb +5 -3
- data/lib/qbot/autorun.rb +0 -2
- data/lib/qbot/base.rb +7 -10
- data/lib/qbot/version.rb +1 -1
- data/qbot.gemspec +1 -1
- metadata +5 -6
- data/lib/qbot/embed/help.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 96175e44e35b00efdc98a08f7dc482c75358a2fa
|
4
|
+
data.tar.gz: f56a2d9a7e9d7634d8c8f1dcbe8a443cad455b05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b03726403afaad4534f48644c27184b7a7df7fa562bbcdae9bd87a67004b816594f5c15d6726e204438793bff9cf0d3b6a27dfa715465168a4194a6bab6f6600
|
7
|
+
data.tar.gz: 0a33dbf259131511157139fefbe1faf4d790a40fc9962a77f8f4ddd962ae5b0a71de90f97748d29cc31219c2168c6f8c7b4d9d77e3b725c72d008f4070c668c6
|
data/README.md
CHANGED
data/lib/qbot/adapter.rb
CHANGED
@@ -12,7 +12,6 @@ module Qbot
|
|
12
12
|
def initialize(url: nil, username: nil, password: nil)
|
13
13
|
@mm_url = url || ENV['QBOT_MATTERMOST_URL']
|
14
14
|
@server = URI.join(@mm_url, '/').to_s
|
15
|
-
@error = false
|
16
15
|
|
17
16
|
resp = api_call(:post, '/users/login', :body => {
|
18
17
|
login_id: username || ENV['QBOT_MATTERMOST_USERNAME'],
|
@@ -20,47 +19,24 @@ module Qbot
|
|
20
19
|
})
|
21
20
|
|
22
21
|
access_token(resp.headers['token'])
|
22
|
+
raise 'Login failed' unless @token
|
23
23
|
end
|
24
24
|
|
25
25
|
def access_token(token)
|
26
26
|
@token = token
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
|
31
|
-
headers = { "Authorization" => "Bearer #{@token}" }
|
32
|
-
|
33
|
-
EM.run do
|
34
|
-
@ws = Faye::WebSocket::Client.new(ws_url, {}, { headers: headers, ping: 60})
|
35
|
-
|
36
|
-
@ws.on :open do |e|
|
37
|
-
Qbot.app.logger.info("#{self.class} - Websocket connection opened")
|
38
|
-
end
|
39
|
-
|
40
|
-
@ws.on :close do |e|
|
41
|
-
Qbot.app.logger.info("#{self.class} - Websocket connection closed")
|
42
|
-
stop if @error
|
43
|
-
on_message(&block) # restart
|
44
|
-
end
|
45
|
-
|
46
|
-
@ws.on :error do |e|
|
47
|
-
Qbot.app.logger.error("#{self.class} - #{e.message}")
|
48
|
-
@error = true
|
49
|
-
end
|
50
|
-
|
51
|
-
@ws.on :message do |e|
|
52
|
-
data = JSON.parse(e.data)
|
53
|
-
emit_event(data, block)
|
54
|
-
end
|
55
|
-
end
|
29
|
+
def listen(&block)
|
30
|
+
EM.run { start_connection(&block) }
|
56
31
|
end
|
57
32
|
|
58
|
-
def
|
33
|
+
def close
|
59
34
|
EM.stop
|
60
35
|
end
|
61
36
|
|
62
37
|
def post(text, **options)
|
63
|
-
api_call(:post, "/posts", body: options.merge(message: text))
|
38
|
+
resp = api_call(:post, "/posts", body: options.merge(message: text))
|
39
|
+
Qbot.app.logger.info("#{self.class} - Post message: #{resp.status} - '#{text}'")
|
64
40
|
end
|
65
41
|
|
66
42
|
def reply_to(message, text, **options)
|
@@ -82,27 +58,54 @@ module Qbot
|
|
82
58
|
URI(@mm_url).path + "/api/v4#{path}"
|
83
59
|
end
|
84
60
|
|
61
|
+
def start_connection(&block)
|
62
|
+
running = true
|
63
|
+
ws_url = URI.join(@server.gsub(/^http(s?):/, 'ws\1:'), endpoint('/websocket')).to_s
|
64
|
+
|
65
|
+
ws = Faye::WebSocket::Client.new(ws_url)
|
66
|
+
ws.send({seq: 1, action: 'authentication_challenge', data: {token: @token}}.to_json)
|
67
|
+
|
68
|
+
ws.on :message do |e|
|
69
|
+
data = JSON.parse(e.data)
|
70
|
+
emit_event(data, block)
|
71
|
+
end
|
72
|
+
|
73
|
+
ws.on :open do |e|
|
74
|
+
Qbot.app.logger.info("#{self.class} - Websocket connection opened")
|
75
|
+
end
|
76
|
+
|
77
|
+
ws.on :close do |e|
|
78
|
+
Qbot.app.logger.info("#{self.class} - Websocket connection closed: #{e.code} #{e.reason}")
|
79
|
+
if running then start_connection(&block) else Qbot.app.stop end
|
80
|
+
end
|
81
|
+
|
82
|
+
ws.on :error do |e|
|
83
|
+
Qbot.app.logger.error("#{self.class} - Websocket encountered error: #{e.message}")
|
84
|
+
running = false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
85
88
|
def emit_event(data, callback)
|
86
|
-
|
87
|
-
Qbot.app.logger.debug("#{self.class} - Event '#{
|
89
|
+
return unless type = data['event']
|
90
|
+
Qbot.app.logger.debug("#{self.class} - Event '#{type}' recieved")
|
88
91
|
|
89
|
-
case
|
90
|
-
when
|
92
|
+
case type
|
93
|
+
when 'posted'
|
91
94
|
post = JSON.parse(data['data']['post'])
|
92
95
|
|
93
96
|
message = Qbot::Message.new
|
94
97
|
message.data = post
|
95
98
|
message.text = post['message']
|
96
99
|
|
97
|
-
Qbot.app.logger.info("#{self.class} - Message was '#{message.text}'")
|
98
100
|
callback.call(message)
|
99
101
|
end
|
102
|
+
rescue => err
|
103
|
+
Qbot.app.logger.error("#{self.class} - ERROR! #{err}")
|
100
104
|
end
|
101
105
|
|
102
106
|
def api_call(method, path, **options, &block)
|
103
107
|
headers = { "Authorization" => "Bearer #{@token}", "Accept" => "application/json" }
|
104
|
-
|
105
|
-
connection = Faraday::Connection.new(url: @server, headers: headers ) do |con|
|
108
|
+
connection = Faraday::Connection.new(url: @server, headers: headers) do |con|
|
106
109
|
con.response :json
|
107
110
|
con.adapter :httpclient
|
108
111
|
end
|
data/lib/qbot/adapter/shell.rb
CHANGED
data/lib/qbot/adapter/slack.rb
CHANGED
@@ -13,7 +13,6 @@ module Qbot
|
|
13
13
|
|
14
14
|
def initialize(api_token: nil)
|
15
15
|
@server = URI.join(SLACK_API_URL, '/').to_s
|
16
|
-
@error = false
|
17
16
|
|
18
17
|
access_token(api_token || ENV['QBOT_SLACK_API_TOKEN'])
|
19
18
|
end
|
@@ -22,42 +21,17 @@ module Qbot
|
|
22
21
|
@token = token
|
23
22
|
end
|
24
23
|
|
25
|
-
def
|
26
|
-
|
27
|
-
data = JSON.parse(resp.body)
|
28
|
-
ws_url = data['url']
|
29
|
-
|
30
|
-
EM.run do
|
31
|
-
@ws = Faye::WebSocket::Client.new(ws_url, {}, { ping: 60})
|
32
|
-
|
33
|
-
@ws.on :open do |e|
|
34
|
-
Qbot.app.logger.info("#{self.class} - Websocket connection opened")
|
35
|
-
end
|
36
|
-
|
37
|
-
@ws.on :close do |e|
|
38
|
-
Qbot.app.logger.info("#{self.class} - Websocket connection closed")
|
39
|
-
stop if @error
|
40
|
-
on_message(&block) # restart
|
41
|
-
end
|
42
|
-
|
43
|
-
@ws.on :error do |e|
|
44
|
-
Qbot.app.logger.error("#{self.class} - #{e.message}")
|
45
|
-
@error = true
|
46
|
-
end
|
47
|
-
|
48
|
-
@ws.on :message do |e|
|
49
|
-
data = JSON.parse(e.data)
|
50
|
-
emit_event(data, block)
|
51
|
-
end
|
52
|
-
end
|
24
|
+
def listen(&block)
|
25
|
+
EM.run { start_connection(&block) }
|
53
26
|
end
|
54
27
|
|
55
|
-
def
|
28
|
+
def close
|
56
29
|
EM.stop
|
57
30
|
end
|
58
31
|
|
59
32
|
def post(text, **options)
|
60
|
-
api_call(:post, "/chat.postMessage", options.merge(text: text))
|
33
|
+
resp = api_call(:post, "/chat.postMessage", options.merge(text: text))
|
34
|
+
Qbot.app.logger.info("#{self.class} - Post message: #{resp.status} - '#{text}'")
|
61
35
|
end
|
62
36
|
|
63
37
|
def reply_to(message, text, **options)
|
@@ -79,19 +53,46 @@ module Qbot
|
|
79
53
|
URI(SLACK_API_URL).path + path
|
80
54
|
end
|
81
55
|
|
56
|
+
def start_connection(&block)
|
57
|
+
resp = api_call(:get, '/rtm.start')
|
58
|
+
data = JSON.parse(resp.body)
|
59
|
+
|
60
|
+
running = true
|
61
|
+
ws_url = data['url']
|
62
|
+
ws = Faye::WebSocket::Client.new(ws_url, nil, {ping: 60})
|
63
|
+
|
64
|
+
ws.on :message do |e|
|
65
|
+
data = JSON.parse(e.data)
|
66
|
+
emit_event(data, block)
|
67
|
+
end
|
68
|
+
|
69
|
+
ws.on :open do |e|
|
70
|
+
Qbot.app.logger.info("#{self.class} - Websocket connection opened")
|
71
|
+
end
|
72
|
+
|
73
|
+
ws.on :close do |e|
|
74
|
+
Qbot.app.logger.info("#{self.class} - Websocket connection closed: #{e.code} #{e.reason}")
|
75
|
+
if running then start_connection(&block) else Qbot.app.stop end
|
76
|
+
end
|
77
|
+
|
78
|
+
ws.on :error do |e|
|
79
|
+
Qbot.app.logger.error("#{self.class} - Websocket encountered error: #{e.message}")
|
80
|
+
running = false
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
82
84
|
def emit_event(data, callback)
|
83
|
-
|
84
|
-
Qbot.app.logger.debug("#{self.class} - Event '#{
|
85
|
+
return unless type = data['event']
|
86
|
+
Qbot.app.logger.debug("#{self.class} - Event '#{type}' recieved")
|
85
87
|
|
86
|
-
case
|
87
|
-
when
|
88
|
+
case type
|
89
|
+
when 'message'
|
88
90
|
return if data['subtype']
|
89
91
|
|
90
92
|
message = Qbot::Message.new
|
91
93
|
message.data = data
|
92
94
|
message.text = data['text']
|
93
95
|
|
94
|
-
Qbot.app.logger.info("#{self.class} - Message was '#{message.text}'")
|
95
96
|
callback.call(message)
|
96
97
|
end
|
97
98
|
end
|
data/lib/qbot/app.rb
CHANGED
@@ -41,16 +41,18 @@ module Qbot
|
|
41
41
|
|
42
42
|
def start
|
43
43
|
@logger.info("Booting #{self.class}.")
|
44
|
-
@logger.info("#{storage.class} - Storage driver loaded")
|
45
|
-
@logger.info("#{adapter.class} - Adapter driver loaded")
|
44
|
+
@logger.info("#{storage.class} - Storage driver loaded.")
|
45
|
+
@logger.info("#{adapter.class} - Adapter driver loaded.")
|
46
|
+
bots.each { |bot| @logger.info("Loading #{bot}.") }
|
46
47
|
|
48
|
+
Thread.abort_on_exception = true
|
47
49
|
@threads << Thread.start { loop { @timers.wait } }
|
48
50
|
@threads << Thread.start { adapter.run(@bots) }
|
49
51
|
@threads.each { |th| th.join }
|
50
52
|
end
|
51
53
|
|
52
54
|
def stop
|
53
|
-
adapter.
|
55
|
+
adapter.close if adapter.respond_to?(:close)
|
54
56
|
@threads.each { |th| th.kill if th }
|
55
57
|
end
|
56
58
|
|
data/lib/qbot/autorun.rb
CHANGED
data/lib/qbot/base.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'parse-cron'
|
2
1
|
require 'dotenv/load'
|
2
|
+
require 'parse-cron'
|
3
3
|
|
4
4
|
require 'qbot/app'
|
5
5
|
require 'qbot/adapter'
|
@@ -22,15 +22,7 @@ module Qbot
|
|
22
22
|
schedule(pattern, &block)
|
23
23
|
end
|
24
24
|
|
25
|
-
def usage(text)
|
26
|
-
on(/^#{prefix}help\s+#{name.downcase}\b/) { post(text) }
|
27
|
-
end
|
28
|
-
|
29
25
|
private
|
30
|
-
def prefix
|
31
|
-
"#{ENV['QBOT_PREFIX']}\s+" if ENV['QBOT_PREFIX']
|
32
|
-
end
|
33
|
-
|
34
26
|
def schedule(pattern, &block)
|
35
27
|
parser = CronParser.new(pattern)
|
36
28
|
current = Time.now
|
@@ -53,7 +45,12 @@ module Qbot
|
|
53
45
|
@message = message
|
54
46
|
return unless @pattern =~ @message.text.to_s.strip
|
55
47
|
|
56
|
-
|
48
|
+
begin
|
49
|
+
Qbot.app.logger.debug("#{self.class} - Recieve message: '#{message.text}'")
|
50
|
+
instance_exec($~, &@callback)
|
51
|
+
rescue => e
|
52
|
+
Qbot.app.logger.error("#{self.class} - Error: #{e}")
|
53
|
+
end
|
57
54
|
end
|
58
55
|
|
59
56
|
def post(text, **options)
|
data/lib/qbot/version.rb
CHANGED
data/qbot.gemspec
CHANGED
@@ -30,6 +30,6 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_dependency "leveldb", "~> 0.1"
|
31
31
|
spec.add_dependency "faraday", "~> 0.14"
|
32
32
|
spec.add_dependency "faraday_middleware", "~> 0.12"
|
33
|
-
spec.add_dependency "httpclient", ">= 2.
|
33
|
+
spec.add_dependency "httpclient", ">= 2.6"
|
34
34
|
spec.add_dependency "faye-websocket", "~> 0.10"
|
35
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qbot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- haccht
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -128,14 +128,14 @@ dependencies:
|
|
128
128
|
requirements:
|
129
129
|
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: '2.
|
131
|
+
version: '2.6'
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '2.
|
138
|
+
version: '2.6'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: faye-websocket
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -175,7 +175,6 @@ files:
|
|
175
175
|
- lib/qbot/base.rb
|
176
176
|
- lib/qbot/embed/cron.rb
|
177
177
|
- lib/qbot/embed/echo.rb
|
178
|
-
- lib/qbot/embed/help.rb
|
179
178
|
- lib/qbot/embed/ping.rb
|
180
179
|
- lib/qbot/storage.rb
|
181
180
|
- lib/qbot/storage/leveldb.rb
|
@@ -202,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
202
201
|
version: '0'
|
203
202
|
requirements: []
|
204
203
|
rubyforge_project:
|
205
|
-
rubygems_version: 2.
|
204
|
+
rubygems_version: 2.6.14.1
|
206
205
|
signing_key:
|
207
206
|
specification_version: 4
|
208
207
|
summary: Tiny chatbot flamework.
|
data/lib/qbot/embed/help.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
|
3
|
-
module Qbot
|
4
|
-
|
5
|
-
class Help < Qbot::Base
|
6
|
-
|
7
|
-
on /^#{prefix}help$/ do |msg|
|
8
|
-
names = Qbot.app.bots
|
9
|
-
.reject { |n| %w(Qbot::Base Qbot::Help).include?(n) }
|
10
|
-
.map { |n| n.split('::').last.downcase }
|
11
|
-
|
12
|
-
next if names.empty?
|
13
|
-
resp = StringIO.new
|
14
|
-
resp.puts 'Features:'
|
15
|
-
resp.puts names.map { |name| " #{name}" }
|
16
|
-
|
17
|
-
post resp.string
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|