ruby-cqhttp 0.0.7 → 0.1.0

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.
@@ -0,0 +1,73 @@
1
+ module Onebot
2
+ # WebSocket连接处理部分
3
+ module WebSocket
4
+ class API
5
+ attr_accessor :queueList
6
+
7
+ def initialize(ws, eventLogger)
8
+ @ws = ws
9
+ @eventLogger = eventLogger
10
+ @queueList = {}
11
+ end
12
+
13
+ def get_msg(message_id, _url = @apiUrl)
14
+ ret = send('get_msg', { message_id: })
15
+ if parseRet(ret)
16
+ @eventLogger.log "获取消息成功 (#{message_id})"
17
+ else
18
+ @eventLogger.log "获取消息失败,错误码: #{ret.msg}, 错误消息: #{ret.wording}", Logger::WARN
19
+ end
20
+ ret[:data]
21
+ end
22
+
23
+ # 发送私聊消息
24
+ #
25
+ # @param msg [String]
26
+ # @param user_id [Number]
27
+ # @return [Hash]
28
+ def sendPrivateMessage(message, user_id)
29
+ ret = send('send_private_msg', { user_id:, message: })
30
+ if parseRet(ret)
31
+ @eventLogger.log "发送至私聊 #{user_id} 的消息: #{message} (#{ret.data.message_id})"
32
+ else
33
+ @eventLogger.log "发送私聊消息失败,错误码: #{ret.msg}, 错误消息: #{ret.wording}", Logger::WARN
34
+ end
35
+ ret[:data]
36
+ end
37
+
38
+ # 发送群聊消息
39
+ #
40
+ # @param msg [String]
41
+ # @param group_id [Number]
42
+ # @return [Hash]
43
+ def sendGroupMessage(message, group_id)
44
+ ret = send('send_group_msg', { group_id:, message: })
45
+ if parseRet(ret)
46
+ @eventLogger.log "发送至群 #{group_id} 的消息: #{message} (#{ret.data.message_id})"
47
+ else
48
+ @eventLogger.log "发送群消息失败,错误码: #{ret.msg}, 错误消息: #{ret.wording}", Logger::WARN
49
+ end
50
+ ret[:data]
51
+ end
52
+
53
+ private
54
+
55
+ #
56
+ # 解析API返回
57
+ #
58
+ def parseRet(ret)
59
+ return true if ret.status == 'ok'
60
+ return false if ret.status == 'failed'
61
+ end
62
+
63
+ def send(action, params)
64
+ echo = Time.now.to_i.to_s
65
+ @ws.send({ action:, params:, echo: }.to_json)
66
+ @queueList[echo] = Queue.new
67
+ ret = @queueList[echo].pop
68
+ @queueList.delete(echo)
69
+ ret
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,69 @@
1
+ module Onebot
2
+ # WebSocket连接处理部分
3
+ module WebSocket
4
+ class Bot
5
+ include EventEmitter
6
+ # @return [Number] self QQ id
7
+ attr_accessor :selfID
8
+
9
+ def initialize(**args); end
10
+
11
+ def method_missing(name, *args, &)
12
+ return @api.send(name, *args, &) if !@api.nil? && @api.respond_to?(name)
13
+
14
+ super
15
+ end
16
+
17
+ def respond_to_missing?(method_name, include_private = false)
18
+ (!@api.nil? && @api.respond_to?(name)) || super
19
+ end
20
+
21
+ # 发送消息
22
+ def sendMessage(msg, session)
23
+ return sendGroupMessage msg, session.group_id if session.message_type == 'group'
24
+ return sendPrivateMessage msg, session.user_id if session.message_type == 'private'
25
+ end
26
+
27
+ private
28
+
29
+ #
30
+ # 消息解析部分
31
+ #
32
+ def dataParse(data)
33
+ msg = JSON.parse(data, symbolize_names: true)
34
+ @eventLogger.dataParse(msg)
35
+ # 连接成功
36
+ if msg.meta_event_type == 'lifecycle' && msg.sub_type == 'connect'
37
+ @selfID = msg.self_id
38
+ emit :logged, @selfID
39
+ end
40
+ #
41
+ # 函数回调
42
+ #
43
+ @api.queueList[msg.echo] << msg if msg.include?(:echo) # 往API模块回调返回消息
44
+ case msg.post_type
45
+ #
46
+ # 请求事件
47
+ #
48
+ when 'request'
49
+ emit :request, msg.request_type, msg
50
+ #
51
+ # 提醒事件
52
+ #
53
+ when 'notice'
54
+ emit :notice, msg.notice_type, msg
55
+ #
56
+ # 消息事件
57
+ #
58
+ when 'message'
59
+ if msg.message_type == 'group' # 判断是否为群聊
60
+ emit :groupMessage, msg
61
+ else
62
+ emit :privateMessage, msg
63
+ end
64
+ emit :message, msg
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,44 @@
1
+ module Onebot
2
+ # WebSocket连接处理部分
3
+ module WebSocket
4
+ class Client < Bot
5
+ # @return [URI] WS URL
6
+ attr_accessor :url
7
+ # @return [Faye::WebSocket::Client] WS Conn
8
+ attr_accessor :ws
9
+ attr_accessor :api
10
+
11
+ # 设置 WS URL
12
+ def initialize(url: nil, logger: nil, **args)
13
+ super
14
+ @eventLogger = Logging::EventLogger.new(logger)
15
+ @url = url
16
+ end
17
+
18
+ # 连接 WS
19
+ def connect(protocols = nil, options = {})
20
+ @eventLogger.log '正在连接到 ' << @url
21
+ EM.run do
22
+ @ws = Faye::WebSocket::Client.new(@url, protocols, options)
23
+ @api = API.new(@ws, @eventLogger)
24
+
25
+ @ws.on :message do |event|
26
+ Thread.new { dataParse(event.data) }
27
+ end
28
+
29
+ @ws.on :close do |event|
30
+ emit :close, event
31
+ @eventLogger.log '连接断开'
32
+ @ws = nil
33
+ EM.stop
34
+ end
35
+
36
+ @ws.on :error do |event|
37
+ emit :error, event
38
+ @ws = nil
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,35 @@
1
+ module Onebot
2
+ # WebSocket连接处理部分
3
+ module WebSocket
4
+ class Server < Bot
5
+ # @return [Faye::WebSocket] ws server
6
+ attr_accessor :ws
7
+ attr_accessor :api
8
+
9
+ require 'rack'
10
+
11
+ def initialize(env:, logger: nil, options: { ping: 5 }, &block)
12
+ super
13
+ @eventLogger = Logging::EventLogger.new(logger)
14
+ @ws = Faye::WebSocket.new(env, %w[irc xmpp], options)
15
+ @api = API.new(@ws, @eventLogger)
16
+ @eventLogger.log(['客户端', '连接', @ws.url, @ws.version], ::Logger::INFO, 'Puma')
17
+
18
+ @ws.on :message do |event|
19
+ Thread.new { dataParse(event.data) }
20
+ end
21
+
22
+ @ws.on :close do |event|
23
+ @eventLogger.log(['客户端', '断开', event.code].to_s, ::Logger::INFO, 'Puma')
24
+ @ws = nil
25
+ end
26
+
27
+ yield self if block_given?
28
+ end
29
+
30
+ def rack_response
31
+ @ws.rack_response
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,44 @@
1
+ require 'faye/websocket'
2
+ require 'json'
3
+ require 'event_emitter'
4
+ require 'net/http'
5
+ require 'logger'
6
+
7
+ class Hash
8
+ def method_missing(m, *a)
9
+ if m.to_s =~ /=$/
10
+ self[Regexp.last_match.pre_match] = a[0]
11
+ elsif a.empty?
12
+ self[m]
13
+ else
14
+ super
15
+ end
16
+ end
17
+
18
+ def respond_to_missing?(m, include_private = false)
19
+ super unless m.to_s =~ /=$/
20
+ end
21
+ end
22
+
23
+ # 一个基于 OneBot 标准的 QQ 机器人框架
24
+ module Onebot
25
+ module Logging
26
+ autoload :Logger, File.expand_path('Core/Logging/Logger', __dir__)
27
+ autoload :EventLogger, File.expand_path('Core/Logging/EventLogger', __dir__)
28
+ end
29
+
30
+ module WebSocket
31
+ autoload :Session, File.expand_path('Core/Websocket/Session', __dir__)
32
+ autoload :API, File.expand_path('Core/Websocket/API', __dir__)
33
+ autoload :Bot, File.expand_path('Core/Websocket/Bot', __dir__)
34
+ autoload :Client, File.expand_path('Core/Websocket/Client', __dir__)
35
+ autoload :Server, File.expand_path('Core/Websocket/Server', __dir__)
36
+ end
37
+
38
+ module Http
39
+ autoload :API, File.expand_path('Core/Http/API', __dir__)
40
+ end
41
+
42
+ autoload :Core, File.expand_path('Core/Core', __dir__)
43
+ autoload :Utils, File.expand_path('Core/Utils', __dir__)
44
+ end
data/ruby-cqhttp.gemspec CHANGED
@@ -3,22 +3,21 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'ruby-cqhttp'
6
- s.version = '0.0.7'
7
- s.summary = '一个基于 OneBot 标准的 QQ 机器人框架'
8
- s.description = '一个基于 OneBot 标准的 QQ 机器人框架'
9
- s.authors = ['fantasyzhjk']
10
- s.email = 'fantasyzhjk@outlook.com'
11
- s.platform = Gem::Platform::RUBY
12
- s.homepage = 'https://github.com/fantasyzhjk/ruby-cqhttp/'
13
- s.license = 'MIT'
14
- s.files = `git ls-files -z`.split("\x0")
6
+ s.version = '0.1.0'
7
+ s.summary = '一个基于 OneBot 标准的 QQ 机器人框架'
8
+ s.description = '一个基于 OneBot 标准的 QQ 机器人框架'
9
+ s.authors = ['fantasyzhjk']
10
+ s.email = 'fantasyzhjk@outlook.com'
11
+ s.platform = Gem::Platform::RUBY
12
+ s.homepage = 'https://github.com/fantasyzhjk/ruby-cqhttp/'
13
+ s.license = 'MIT'
14
+ s.files = `git ls-files -z`.split("\x0")
15
15
  s.require_paths = ['lib']
16
16
  s.required_ruby_version = '>= 2.7.0'
17
17
 
18
- s.add_runtime_dependency 'json'
19
- s.add_runtime_dependency 'logger'
20
- s.add_runtime_dependency 'uri', '~> 0.10.1'
21
- s.add_runtime_dependency 'eventmachine'
22
- s.add_runtime_dependency 'faye-websocket'
23
- s.add_runtime_dependency 'event_emitter'
18
+ s.add_runtime_dependency 'event_emitter'
19
+ s.add_runtime_dependency 'faye-websocket'
20
+ s.add_runtime_dependency 'json'
21
+ s.add_runtime_dependency 'logger'
22
+ s.add_runtime_dependency 'rack'
24
23
  end
data/tests/client.rb ADDED
@@ -0,0 +1,21 @@
1
+ require '../lib/onebot-ruby'
2
+
3
+ logger = Onebot::Logging::Logger.new.setLoggerLevel(Logger::INFO)
4
+ api = Onebot::Http::API.new.setLogger(logger)
5
+
6
+ Onebot::Core.connect url: 'ws://localhost:7700', logger: logger, options: { headers: { 'Authorization' => 'Bearer xxxxxxxxxxxx' } } do |bot|
7
+ bot.on :logged do |_botqq|
8
+ logger.log('我开了欸')
9
+ end
10
+
11
+ bot.on :privateMessage do |session|
12
+ bot.sendMessage(session.message, session)
13
+ end
14
+
15
+ bot.on :notice do |notice_type, data|
16
+ if notice_type == 'friend_recall'
17
+ req = bot.get_msg(data.message_id)
18
+ bot.sendPrivateMessage req.message, req.sender.user_id
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ Rainbows! do
2
+ use :EventMachine
3
+ end
data/tests/server.rb ADDED
@@ -0,0 +1,77 @@
1
+ require '../lib/onebot-ruby'
2
+ require 'faye/websocket'
3
+ require 'rack'
4
+
5
+ logger = Onebot::Logging::Logger.new.setLoggerLevel(Logger::INFO)
6
+ static = Rack::File.new(File.dirname(__FILE__))
7
+ options = { ping: 5 }
8
+
9
+ App = lambda do |env|
10
+ if Faye::WebSocket.websocket?(env)
11
+ bot = Onebot::WebSocket::Server.new(env:, logger:, options:)
12
+
13
+ bot.on :logged do |_botqq|
14
+ logger.log('我开了欸')
15
+ end
16
+
17
+ bot.on :privateMessage do |session|
18
+ # p session.message
19
+ # p session
20
+ p Onebot::Utils.cqParse(session.message)
21
+ bot.sendPrivateMessage(session.message, session.userId)
22
+ end
23
+
24
+ bot.rack_response
25
+ else
26
+ static.call(env)
27
+ end
28
+ end
29
+
30
+ def App.log(message); end
31
+
32
+ port = ARGV[0] || 7000
33
+ secure = ARGV[1] == 'tls'
34
+ engine = ARGV[2] || 'thin'
35
+ spec = File.expand_path(__dir__)
36
+
37
+ Faye::WebSocket.load_adapter(engine)
38
+
39
+ case engine
40
+
41
+ when 'goliath'
42
+ class WebSocketServer < Goliath::API
43
+ def response(env)
44
+ App.call(env)
45
+ end
46
+ end
47
+
48
+ when 'puma'
49
+ require 'puma/binder'
50
+ require 'puma/events'
51
+ events = Puma::Events.new($stdout, $stderr)
52
+ binder = Puma::Binder.new(events)
53
+ binder.parse(["tcp://0.0.0.0:#{port}"], App)
54
+ server = Puma::Server.new(App, events)
55
+ server.binder = binder
56
+ server.run.join
57
+
58
+ when 'rainbows'
59
+ rackup = Unicorn::Configurator::RACKUP
60
+ rackup[:port] = port
61
+ rackup[:set_listener] = true
62
+ options = rackup[:options]
63
+ options[:config_file] = File.expand_path('rainbows.conf', __dir__)
64
+ Rainbows::HttpServer.new(App, options).start.join
65
+
66
+ when 'thin'
67
+ thin = Rack::Handler.get('thin')
68
+ thin.run(App, Host: '0.0.0.0', Port: port) do |server|
69
+ if secure
70
+ server.ssl_options = {
71
+ private_key_file: spec + '/server.key',
72
+ cert_chain_file: spec + '/server.crt'
73
+ }
74
+ server.ssl = true
75
+ end
76
+ end
77
+ end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-cqhttp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - fantasyzhjk
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-24 00:00:00.000000000 Z
11
+ date: 2022-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: json
14
+ name: event_emitter
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: logger
28
+ name: faye-websocket
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,21 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: uri
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 0.10.1
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 0.10.1
55
- - !ruby/object:Gem::Dependency
56
- name: eventmachine
42
+ name: json
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - ">="
@@ -67,7 +53,7 @@ dependencies:
67
53
  - !ruby/object:Gem::Version
68
54
  version: '0'
69
55
  - !ruby/object:Gem::Dependency
70
- name: faye-websocket
56
+ name: logger
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
59
  - - ">="
@@ -81,7 +67,7 @@ dependencies:
81
67
  - !ruby/object:Gem::Version
82
68
  version: '0'
83
69
  - !ruby/object:Gem::Dependency
84
- name: event_emitter
70
+ name: rack
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - ">="
@@ -100,19 +86,31 @@ executables: []
100
86
  extensions: []
101
87
  extra_rdoc_files: []
102
88
  files:
89
+ - ".bundle/config"
103
90
  - ".gitignore"
91
+ - ".rubocop.yml"
104
92
  - Gemfile
105
93
  - README.md
106
- - lib/Bot/Api.rb
107
- - lib/Bot/Bot.rb
108
- - lib/Bot/Utils.rb
109
- - lib/ruby-cqhttp.rb
94
+ - icon.png
95
+ - lib/Core/Core.rb
96
+ - lib/Core/Http/API.rb
97
+ - lib/Core/Logging/EventLogger.rb
98
+ - lib/Core/Logging/Logger.rb
99
+ - lib/Core/Utils.rb
100
+ - lib/Core/WebSocket/API.rb
101
+ - lib/Core/WebSocket/Bot.rb
102
+ - lib/Core/WebSocket/Client.rb
103
+ - lib/Core/WebSocket/Server.rb
104
+ - lib/onebot-ruby.rb
110
105
  - ruby-cqhttp.gemspec
106
+ - tests/client.rb
107
+ - tests/rainbows.conf
108
+ - tests/server.rb
111
109
  homepage: https://github.com/fantasyzhjk/ruby-cqhttp/
112
110
  licenses:
113
111
  - MIT
114
112
  metadata: {}
115
- post_install_message:
113
+ post_install_message:
116
114
  rdoc_options: []
117
115
  require_paths:
118
116
  - lib
@@ -127,8 +125,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
125
  - !ruby/object:Gem::Version
128
126
  version: '0'
129
127
  requirements: []
130
- rubygems_version: 3.1.4
131
- signing_key:
128
+ rubygems_version: 3.3.7
129
+ signing_key:
132
130
  specification_version: 4
133
131
  summary: 一个基于 OneBot 标准的 QQ 机器人框架
134
132
  test_files: []