ruby-cqhttp 0.0.3 → 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,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,19 +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.3'
7
- s.date = '2020-11-04'
8
- s.summary = 'ruby-cqhttp for osucat'
9
- s.description = 'ruby-cqhttp for osucat'
10
- s.authors = ['fantasyzhjk']
11
- s.email = 'fantasyzhjk@outlook.com'
12
- s.files = ['lib/ruby-cqhttp.rb']
13
- s.homepage = 'http://rubygems.org/gems/ruby-cqhttp'
14
- s.license = 'MIT'
15
- 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")
16
15
  s.require_paths = ['lib']
16
+ s.required_ruby_version = '>= 2.7.0'
17
17
 
18
- # s.add_runtime_dependency 'json', '~> 1.1'
19
- # s.add_runtime_dependency 'eventmachine', '~> 1.1'
20
- # s.add_runtime_dependency 'faye-websocket', '~> 1.1'
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'
21
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,31 +1,116 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-cqhttp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
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: 2020-11-04 00:00:00.000000000 Z
12
- dependencies: []
13
- description: ruby-cqhttp for osucat
11
+ date: 2022-05-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: event_emitter
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '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'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: logger
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: 一个基于 OneBot 标准的 QQ 机器人框架
14
84
  email: fantasyzhjk@outlook.com
15
85
  executables: []
16
86
  extensions: []
17
87
  extra_rdoc_files: []
18
88
  files:
19
- - lib/Bot/Api.rb
20
- - lib/Bot/Bot.rb
21
- - lib/Bot/Utils.rb
22
- - lib/ruby-cqhttp.rb
89
+ - ".bundle/config"
90
+ - ".gitignore"
91
+ - ".rubocop.yml"
92
+ - Gemfile
93
+ - README.md
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
23
105
  - ruby-cqhttp.gemspec
24
- homepage: http://rubygems.org/gems/ruby-cqhttp
106
+ - tests/client.rb
107
+ - tests/rainbows.conf
108
+ - tests/server.rb
109
+ homepage: https://github.com/fantasyzhjk/ruby-cqhttp/
25
110
  licenses:
26
111
  - MIT
27
112
  metadata: {}
28
- post_install_message:
113
+ post_install_message:
29
114
  rdoc_options: []
30
115
  require_paths:
31
116
  - lib
@@ -33,15 +118,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
33
118
  requirements:
34
119
  - - ">="
35
120
  - !ruby/object:Gem::Version
36
- version: '0'
121
+ version: 2.7.0
37
122
  required_rubygems_version: !ruby/object:Gem::Requirement
38
123
  requirements:
39
124
  - - ">="
40
125
  - !ruby/object:Gem::Version
41
126
  version: '0'
42
127
  requirements: []
43
- rubygems_version: 3.0.3
44
- signing_key:
128
+ rubygems_version: 3.3.7
129
+ signing_key:
45
130
  specification_version: 4
46
- summary: ruby-cqhttp for osucat
131
+ summary: 一个基于 OneBot 标准的 QQ 机器人框架
47
132
  test_files: []
data/lib/Bot/Api.rb DELETED
@@ -1,105 +0,0 @@
1
- module CQHttp
2
- class Api
3
- attr_accessor :apiUrl
4
-
5
- @apiUrl = 'http://127.0.0.1:5700'
6
- class << self
7
- def setGroupName(group_id, group_name, url=@apiUrl)
8
- ret = { group_id: group_id.to_i, group_name: group_name }.to_json
9
- data = JSON.parse(Utils.httpPost("#{url}/set_group_name", ret))
10
- if data['status'] == 'ok'
11
- Utils.log Time.new, '√', '设置群头像成功'
12
- else
13
- Utils.log Time.new, '×', '设置群头像失败'
14
- end
15
- end
16
-
17
- def getImage(file, url=@apiUrl) # UNFINSHED
18
- ret = { file: file }.to_json
19
- data = JSON.parse(Utils.httpPost("#{url}/get_image", ret))
20
- if data['status'] == 'ok'
21
- Utils.log Time.new, '√', '下载图片成功'
22
- return data['data']
23
- else
24
- Utils.log Time.new, '×', '下载图片失败'
25
- end
26
- end
27
-
28
- def get_msg(message_id, url=@apiUrl) # UNFINSHED
29
- ret = { message_id: message_id }.to_json
30
- data = JSON.parse(Utils.httpPost("#{url}/get_msg", ret))
31
- if data['status'] == 'ok'
32
- Utils.log Time.new, '√', '消息获取成功'
33
- return data['data']
34
- else
35
- Utils.log Time.new, '×', '消息获取失败'
36
- end
37
-
38
- end
39
-
40
- def sendPrivateMessage(msg, user_id, url=@apiUrl)
41
- ret = { user_id: user_id, message: msg }.to_json
42
- data = JSON.parse(Utils.httpPost("#{url}/send_private_msg", ret))
43
- if data['status'] == 'ok'
44
- message_id = data['data']['message_id']
45
- Utils.log Time.new, '↑', "发送至私聊 #{user_id} 的消息: #{msg} (#{message_id})"
46
- return message_id
47
- else
48
- Utils.log Time.new, '×', '发送消息失败'
49
- end
50
- end
51
-
52
- def sendGroupMessage(msg, group_id, url=@apiUrl)
53
- ret = { group_id: group_id, message: msg }.to_json
54
- data = JSON.parse(Utils.httpPost("#{url}/send_group_msg", ret))
55
- if data['status'] == 'ok'
56
- message_id = data['data']['group_id']
57
- Utils.log Time.new, '↑', "发送至群 #{user_id} 的消息: #{msg} (#{message_id})"
58
- return message_id
59
- else
60
- Utils.log Time.new, '×', '发送消息失败'
61
- end
62
- end
63
-
64
- def acceptFriendRequest(flag, url=@apiUrl)
65
- ret = { flag: flag, approve: true }.to_json
66
- data = JSON.parse(Utils.httpPost("#{url}/set_friend_add_request", ret))
67
- if data['status'] == 'ok'
68
- Utils.log Time.new, '√', '已通过好友请求'
69
- else
70
- Utils.log Time.new, '×', '请求通过失败'
71
- end
72
- end
73
-
74
- def refuseFriendRequest(flag, url=@apiUrl)
75
- ret = { flag: flag, approve: false }.to_json
76
- user_id = JSON.parse(Utils.httpPost("#{url}/set_friend_add_request", ret))
77
- if data['status'] == 'ok'
78
- Utils.log Time.new, '√', '已拒绝好友请求'
79
- else
80
- Utils.log Time.new, '×', '请求拒绝失败'
81
- end
82
- end
83
-
84
- def acceptGroupRequest(flag, sub_type, url=@apiUrl)
85
- ret = { flag: flag, sub_type: sub_type, approve: true }.to_json
86
- data = JSON.parse(Utils.httpPost("#{url}/set_group_add_request", ret))
87
- if data['status'] == 'ok'
88
- Utils.log Time.new, '√', '已通过加群请求'
89
- else
90
- Utils.log Time.new, '×', '请求通过失败'
91
- end
92
- end
93
-
94
- def refuseGroupRequest(flag, sub_type, url=@apiUrl)
95
- ret = { flag: flag, sub_type: sub_type, approve: false }.to_json
96
- data = JSON.parse(Utils.httpPost("#{url}/set_group_add_request", ret))
97
- if data['status'] == 'ok'
98
- Utils.log Time.new, '√', '已拒绝加群请求'
99
- else
100
- Utils.log Time.new, '×', '请求拒绝失败'
101
- end
102
- end
103
- end
104
- end
105
- end