ruby-cqhttp 0.0.6 → 0.1.2

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,141 @@
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 = sendReq('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 = sendReq('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 = sendReq('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
+ # 接受好友邀请
54
+ #
55
+ # @param flag [String]
56
+ # @param reason [String]
57
+ # @param url [URI]
58
+ # @return [Boolean]
59
+ def acceptFriendRequest(flag, reason = nil)
60
+ data = sendReq('set_friend_add_request', { flag:, approve: true, remark: reason })
61
+ if parseRet(data)
62
+ @logger.log '已通过好友请求'
63
+ true
64
+ else
65
+ @logger.log '请求通过失败', Logger::WARN
66
+ false
67
+ end
68
+ end
69
+
70
+ # 拒绝好友邀请
71
+ #
72
+ # @param flag [String]
73
+ # @param url [URI]
74
+ # @return [Boolean]
75
+ def refuseFriendRequest(flag)
76
+ data = sendReq('set_friend_add_request', { flag:, approve: false })
77
+ if parseRet(data)
78
+ @logger.log '已拒绝好友请求'
79
+ true
80
+ else
81
+ @logger.log '请求拒绝失败', Logger::WARN
82
+ false
83
+ end
84
+ end
85
+
86
+ # 接受加群请求
87
+ #
88
+ # @param flag [String]
89
+ # @param sub_type [String]
90
+ # @param url [URI]
91
+ # @return [Boolean]
92
+ def acceptGroupRequest(flag, sub_type)
93
+ data = sendReq('set_group_add_request', { flag:, sub_type:, approve: true })
94
+ if parseRet(data)
95
+ @logger.log '已通过加群请求'
96
+ true
97
+ else
98
+ @logger.log '请求通过失败', Logger::WARN
99
+ false
100
+ end
101
+ end
102
+
103
+ # 拒绝加群请求
104
+ #
105
+ # @param flag [String]
106
+ # @param sub_type [String]
107
+ # @param reason [String]
108
+ # @param url [URI]
109
+ # @return [Boolean]
110
+ def refuseGroupRequest(flag, sub_type, reason = nil)
111
+ data = sendReq('set_group_add_request', { flag:, sub_type:, approve: false, reason: })
112
+ if parseRet(data)
113
+ @logger.log '已拒绝加群请求'
114
+ true
115
+ else
116
+ @logger.log '请求拒绝失败', Logger::WARN
117
+ false
118
+ end
119
+ end
120
+
121
+ private
122
+
123
+ #
124
+ # 解析API返回
125
+ #
126
+ def parseRet(ret)
127
+ return true if ret.status == 'ok'
128
+ return false if ret.status == 'failed'
129
+ end
130
+
131
+ def sendReq(action, params)
132
+ echo = Time.now.to_i.to_s
133
+ @ws.send({ action:, params:, echo: }.to_json)
134
+ @queueList[echo] = Queue.new
135
+ ret = @queueList[echo].pop
136
+ @queueList.delete(echo)
137
+ ret
138
+ end
139
+ end
140
+ end
141
+ 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,23 +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.6'
7
- s.date = '2021-03-23'
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.platform = Gem::Platform::RUBY
13
- s.homepage = 'https://github.com/fantasyzhjk/ruby-cqhttp/'
14
- s.license = 'MIT'
15
- s.files = `git ls-files -z`.split("\x0")
6
+ s.version = '0.1.2'
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']
17
16
  s.required_ruby_version = '>= 2.7.0'
18
17
 
19
- s.add_runtime_dependency 'json'
20
- s.add_runtime_dependency 'logger'
21
- s.add_runtime_dependency 'uri', '~> 0.10.1'
22
- s.add_runtime_dependency 'eventmachine'
23
- s.add_runtime_dependency 'faye-websocket'
24
- 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'
25
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 |data|
12
+ bot.sendMessage(session.message, data)
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 |data|
18
+ # p data.message
19
+ # p data
20
+ p Onebot::Utils.cqParse(data.message)
21
+ bot.sendPrivateMessage(data.message, data.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.6
4
+ version: 0.1.2
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-23 00:00:00.000000000 Z
11
+ date: 2022-05-18 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
  - - ">="
@@ -94,25 +80,37 @@ dependencies:
94
80
  - - ">="
95
81
  - !ruby/object:Gem::Version
96
82
  version: '0'
97
- description: ruby-cqhttp for osucat
83
+ description: 一个基于 OneBot 标准的 QQ 机器人框架
98
84
  email: fantasyzhjk@outlook.com
99
85
  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.2
131
- signing_key:
128
+ rubygems_version: 3.3.7
129
+ signing_key:
132
130
  specification_version: 4
133
- summary: ruby-cqhttp for osucat
131
+ summary: 一个基于 OneBot 标准的 QQ 机器人框架
134
132
  test_files: []