qbot 0.1.1 → 0.1.3

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
- SHA256:
3
- metadata.gz: 85d73bad55f14325b0a78aeaff2341de02ef5614aa2fffe440bf67a2a3b70b74
4
- data.tar.gz: 4482b338249e3c9fa3f480768f41dde54e160220929b0d6bd58e9e2a7679ad20
2
+ SHA1:
3
+ metadata.gz: 96175e44e35b00efdc98a08f7dc482c75358a2fa
4
+ data.tar.gz: f56a2d9a7e9d7634d8c8f1dcbe8a443cad455b05
5
5
  SHA512:
6
- metadata.gz: a4cc7f82c33ba57018a77b0cfadfe8c168647d0d00c53722bc894ea741dc250c1cfa042814c53673a4f12ac512a55304335be7ecf9a8917ccdd2673f084ffde4
7
- data.tar.gz: d8a08ddb77ede43079f68587967d5e70902df0ab2a9fbcb05d8ad3ade91cd0f95482e4ae7c97d3456d20577c477ad60d985c1366904ba62337bb0ee21087d3fb
6
+ metadata.gz: b03726403afaad4534f48644c27184b7a7df7fa562bbcdae9bd87a67004b816594f5c15d6726e204438793bff9cf0d3b6a27dfa715465168a4194a6bab6f6600
7
+ data.tar.gz: 0a33dbf259131511157139fefbe1faf4d790a40fc9962a77f8f4ddd962ae5b0a71de90f97748d29cc31219c2168c6f8c7b4d9d77e3b725c72d008f4070c668c6
data/README.md CHANGED
@@ -43,7 +43,7 @@ end
43
43
  Then put your Slack API Token in `.env`.
44
44
 
45
45
  ```
46
- QBOT_SLACK_API_TOKEN=xoxb-############-#######################C
46
+ QBOT_SLACK_API_TOKEN=xoxb-############-########################
47
47
  ```
48
48
 
49
49
  And now start your bot with the following command.
@@ -19,12 +19,12 @@ module Qbot
19
19
  end
20
20
 
21
21
  def run(bots)
22
- on_message do |message|
22
+ listen do |message|
23
23
  bots.each { |bot| bot.call(message.dup) }
24
24
  end
25
25
  end
26
26
 
27
- def on_message(&block)
27
+ def listen(&block)
28
28
  raise 'Not implemented'
29
29
  end
30
30
 
@@ -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 on_message(&block)
30
- ws_url = URI.join(@server.gsub(/^http(s?):/, 'ws\1:'), endpoint('/websocket')).to_s
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 stop
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
- event = data['event'].to_sym
87
- Qbot.app.logger.debug("#{self.class} - Event '#{event}' recieved")
89
+ return unless type = data['event']
90
+ Qbot.app.logger.debug("#{self.class} - Event '#{type}' recieved")
88
91
 
89
- case event
90
- when :posted
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
@@ -27,10 +27,14 @@ module Qbot
27
27
  end
28
28
  end
29
29
 
30
- def on_message(&block)
30
+ def listen(&block)
31
31
  EM.run { EM.open_keyboard(Keyboard, block) }
32
32
  end
33
33
 
34
+ def close
35
+ EM.stop
36
+ end
37
+
34
38
  def post(text, **options)
35
39
  $stdout.puts text
36
40
  end
@@ -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 on_message(&block)
26
- resp = api_call(:get, '/rtm.start')
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 stop
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
- event = data['type'].to_sym
84
- Qbot.app.logger.debug("#{self.class} - Event '#{event}' recieved")
85
+ return unless type = data['event']
86
+ Qbot.app.logger.debug("#{self.class} - Event '#{type}' recieved")
85
87
 
86
- case event
87
- when :message
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
@@ -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.stop if adapter.respond_to?(:stop)
55
+ adapter.close if adapter.respond_to?(:close)
54
56
  @threads.each { |th| th.kill if th }
55
57
  end
56
58
 
@@ -1,5 +1,3 @@
1
- require 'qbot/embed/help'
2
-
3
1
  module Qbot
4
2
 
5
3
  def self.autorun
@@ -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
- instance_exec($~, &@callback)
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)
@@ -1,3 +1,3 @@
1
1
  module Qbot
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -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.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.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-08-31 00:00:00.000000000 Z
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.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.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.7.6
204
+ rubygems_version: 2.6.14.1
206
205
  signing_key:
207
206
  specification_version: 4
208
207
  summary: Tiny chatbot flamework.
@@ -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