ruby-cqhttp 0.0.7 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/Bot/Api.rb DELETED
@@ -1,188 +0,0 @@
1
- module CQHttp
2
- # OneBot标准API
3
- # [OneBot文档] (https://github.com/howmanybots/onebot)
4
- #
5
- # Example:
6
- # CQHttp::Api.getImage file
7
- class Api
8
- # @return [URI] HTTP API链接
9
- attr_accessor :apiUrl
10
- class << self
11
-
12
- # 设置API地址
13
- #
14
- # @param apiIp [String]
15
- # @param apiPort [Number]
16
- # @return [URI]
17
- def setUrl(apiIp:'127.0.0.1', apiPort:5700)
18
- @apiUrl = URI::HTTP.build(host: apiIp, port: apiPort)
19
- end
20
-
21
- # 设置群名
22
- #
23
- # @param group_id [Number]
24
- # @param group_name [String]
25
- # @param url [URI]
26
- # @return [Hash]
27
- def setGroupName(group_id, group_name, url=@apiUrl)
28
- url.path = "/set_group_name"
29
- ret = { group_id: group_id.to_i, group_name: group_name }.to_json
30
- data = JSON.parse(Utils.httpPost(url, ret))
31
- if data['status'] == 'ok'
32
- Utils.log '设置群头像成功'
33
- else
34
- Utils.log '设置群头像失败', Logger::WARN
35
- end
36
- return data['data']
37
- end
38
-
39
- # 下载图片(未完成)
40
- #
41
- # @param file [String]
42
- # @param url [URI]
43
- # @return [Hash]
44
- def getImage(file, url=@apiUrl)
45
- url.path = "/get_image"
46
- ret = { file: file }.to_json
47
- data = JSON.parse(Utils.httpPost(url, ret))
48
- if data['status'] == 'ok'
49
- Utils.log '下载图片成功'
50
- else
51
- Utils.log '下载图片失败', Logger::WARN
52
- end
53
- return data['data']
54
- end
55
-
56
- # 获取消息
57
- #
58
- # @param message_id [Number]
59
- # @param url [URI]
60
- # @return [Hash]
61
- def get_msg(message_id, url=@apiUrl)
62
- url.path = "/get_msg"
63
- ret = { message_id: message_id }.to_json
64
- data = JSON.parse(Utils.httpPost(url, ret))
65
- if data['status'] == 'ok'
66
- Utils.log '消息获取成功'
67
- else
68
- Utils.log '消息获取失败', Logger::WARN
69
- end
70
- return data['data']
71
- end
72
-
73
- # 发送私聊消息
74
- #
75
- # @param msg [String]
76
- # @param user_id [Number]
77
- # @param url [URI]
78
- # @return [Hash]
79
- def sendPrivateMessage(msg, user_id, url=@apiUrl)
80
- url.path = "/send_private_msg"
81
- ret = { user_id: user_id, message: msg }.to_json
82
- data = JSON.parse(Utils.httpPost(url, ret))
83
- if data['status'] == 'ok'
84
- message_id = data['data']['message_id']
85
- Utils.log "发送至私聊 #{user_id} 的消息: #{msg} (#{message_id})"
86
- else
87
- Utils.log '发送消息失败', Logger::WARN
88
- end
89
- return data['data']
90
- end
91
-
92
- # 发送群聊消息
93
- #
94
- # @param msg [String]
95
- # @param group_id [Number]
96
- # @param url [URI]
97
- # @return [Hash]
98
- def sendGroupMessage(msg, group_id, url=@apiUrl)
99
- url.path = "/send_group_msg"
100
- ret = { group_id: group_id, message: msg }.to_json
101
- data = JSON.parse(Utils.httpPost(url, ret))
102
- if data['status'] == 'ok'
103
- message_id = data['data']['message_id']
104
- Utils.log "发送至群 #{group_id} 的消息: #{msg} (#{message_id})"
105
- else
106
- Utils.log '发送消息失败', Logger::WARN
107
- end
108
- return data['data']
109
- end
110
-
111
- # 接受好友邀请
112
- #
113
- # @param flag [String]
114
- # @param reason [String]
115
- # @param url [URI]
116
- # @return [Boolean]
117
- def acceptFriendRequest(flag, reason=nil, url=@apiUrl)
118
- url.path = "/set_friend_add_request"
119
- ret = { flag: flag, approve: true, remark: reason }.to_json
120
- data = JSON.parse(Utils.httpPost(url, ret))
121
- if data['status'] == 'ok'
122
- Utils.log '已通过好友请求'
123
- true
124
- else
125
- Utils.log '请求通过失败', Logger::WARN
126
- false
127
- end
128
- end
129
-
130
- # 拒绝好友邀请
131
- #
132
- # @param flag [String]
133
- # @param url [URI]
134
- # @return [Boolean]
135
- def refuseFriendRequest(flag, url=@apiUrl)
136
- url.path = "/set_friend_add_request"
137
- ret = { flag: flag, approve: false }.to_json
138
- user_id = JSON.parse(Utils.httpPost(url, ret))
139
- if data['status'] == 'ok'
140
- Utils.log '已拒绝好友请求'
141
- true
142
- else
143
- Utils.log '请求拒绝失败', Logger::WARN
144
- false
145
- end
146
- end
147
-
148
- # 接受加群请求
149
- #
150
- # @param flag [String]
151
- # @param sub_type [String]
152
- # @param url [URI]
153
- # @return [Boolean]
154
- def acceptGroupRequest(flag, sub_type, url=@apiUrl)
155
- url.path = "/set_group_add_request"
156
- ret = { flag: flag, sub_type: sub_type, approve: true }.to_json
157
- data = JSON.parse(Utils.httpPost(url, ret))
158
- if data['status'] == 'ok'
159
- Utils.log '已通过加群请求'
160
- true
161
- else
162
- Utils.log '请求通过失败', Logger::WARN
163
- false
164
- end
165
- end
166
-
167
- # 拒绝加群请求
168
- #
169
- # @param flag [String]
170
- # @param sub_type [String]
171
- # @param reason [String]
172
- # @param url [URI]
173
- # @return [Boolean]
174
- def refuseGroupRequest(flag, sub_type, reason=nil, url=@apiUrl)
175
- url.path = "/set_group_add_request"
176
- ret = { flag: flag, sub_type: sub_type, approve: false, reason: reason }.to_json
177
- data = JSON.parse(Utils.httpPost(url, ret))
178
- if data['status'] == 'ok'
179
- Utils.log '已拒绝加群请求'
180
- true
181
- else
182
- Utils.log '请求拒绝失败', Logger::WARN
183
- false
184
- end
185
- end
186
- end
187
- end
188
- end
data/lib/Bot/Bot.rb DELETED
@@ -1,255 +0,0 @@
1
- module CQHttp
2
- # 消息处理,ws连接
3
- #
4
- # Example:
5
- # CQHttp::Bot.connect host: host, port: port {|bot| ... }
6
- class Bot
7
- # 发送人信息
8
- #
9
- # @!attribute age
10
- # @return [Number] 年龄
11
- # @!attribute member_role
12
- # @return [String] 角色,owner 或 admin 或 member
13
- # @!attribute card
14
- # @return [String] 群名片/备注
15
- # @!attribute user_id
16
- # @return [Number] 发送者 QQ 号
17
- # @!attribute qqlevel
18
- # @return [String] 成员等级
19
- # @!attribute nickname
20
- # @return [String] 昵称
21
- # @!attribute title
22
- # @return [String] 专属头衔
23
- # @!attribute sex
24
- # @return [String] 性别,male 或 female 或 unknown
25
- Sender = Struct.new(:age, :member_role, :card, :user_id, :qqlevel, :nickname, :title, :sex)
26
- # 消息事件数据
27
- #
28
- # @!attribute messagetype
29
- # @return [String] 成员等级
30
- # @!attribute time
31
- # @return [Number] 事件发生的时间戳
32
- # @!attribute group_id
33
- # @return [Number] 群号
34
- # @!attribute user_id
35
- # @return [Number] 发送者 QQ 号
36
- # @!attribute message_id
37
- # @return [Number] 消息 ID
38
- # @!attribute message
39
- # @return [String] 消息内容
40
- # @!attribute raw_message
41
- # @return [String] 原始消息内容
42
- # @!attribute sub_type
43
- # @return [String] 消息子类型,私聊中如果是好友则是 friend,如果是群临时会话则是 group,群聊中正常消息是 normal,匿名消息是 anonymous,系统提示(如「管理员已禁止群内匿名聊天」)是 notice
44
- # @!attribute anonymous
45
- # @return [Hash] 匿名信息,如果不是匿名消息则为 null
46
- Target = Struct.new(:messagetype, :time, :group_id, :user_id, :message_id, :message, :raw_message, :sub_type, :anonymous)
47
-
48
- # 新建连接
49
- #
50
- # @param host [String]
51
- # @param port [Number]
52
- # @return [WebSocket]
53
- def self.connect(host:, port:)
54
- url = URI::WS.build(host: host, port: port)
55
- Api.setUrl()
56
- Utils.log '正在连接到 ' << url.to_s
57
- client = ::CQHttp::Bot::WebSocket.new(url)
58
- yield client if block_given?
59
- client.connect
60
- client
61
- end
62
-
63
- # WebSocket连接处理部分
64
- class WebSocket
65
- # @return [URI] WS URL
66
- attr_accessor :url
67
- # @return [Faye::WebSocket::Client] WS Conn
68
- attr_accessor :ws
69
- # @return [Number] self QQ id
70
- attr_accessor :selfID
71
-
72
- include EventEmitter
73
-
74
- # 设置 WS URL
75
- def initialize(url)
76
- @queueList = {}
77
- @url = url
78
- end
79
-
80
- # 连接 WS
81
- def connect
82
- EM.run do
83
- @ws = Faye::WebSocket::Client.new(@url.to_s)
84
-
85
- @ws.on :message do |event|
86
- Thread.new { dataParse(event.data) }
87
- end
88
-
89
- @ws.on :close do |event|
90
- emit :close, event
91
- Utils.log '连接断开'
92
- @ws = nil
93
- exit
94
- end
95
-
96
- @ws.on :error do |event|
97
- emit :error, event
98
- @ws = nil
99
- end
100
- end
101
- end
102
-
103
- # 发送私聊消息
104
- #
105
- # @param msg [String]
106
- # @param user_id [Number]
107
- # @return [Hash]
108
- def sendPrivateMessage(msg, user_id)
109
- echo = Time.now.to_i.to_s
110
- params = { action: 'send_private_msg', params: { user_id: user_id, message: msg }, echo: echo }.to_json
111
- @ws.send params
112
- @queueList[echo] = Queue.new
113
- ret = @queueList[echo].pop
114
- if parseRet(ret)
115
- Utils.log "发送至私聊 #{user_id} 的消息: #{msg} (#{ret['data']['message_id']})"
116
- else
117
- Utils.log "发送消息失败,错误码: #{ret['msg']}, 错误消息: #{ret['wording']}", Logger::WARN
118
- end
119
- return ret['data']
120
- end
121
-
122
- # 发送群聊消息
123
- #
124
- # @param msg [String]
125
- # @param group_id [Number]
126
- # @return [Hash]
127
- def sendGroupMessage(msg, group_id)
128
- echo = Time.now.to_i.to_s
129
- params = { action: 'send_group_msg', params: { group_id: group_id, message: msg }, echo: echo }.to_json
130
- @ws.send params
131
- @queueList[echo] = Queue.new
132
- ret = @queueList[echo].pop
133
- @queueList.delete(echo)
134
- if parseRet(ret)
135
- Utils.log "发送至群 #{group_id} 的消息: #{msg} (#{ret['data']['message_id']})"
136
- else
137
- Utils.log "发送消息失败,错误码: #{ret['msg']}, 错误消息: #{ret['wording']}", Logger::WARN
138
- end
139
- return ret['data']
140
- end
141
-
142
- # 发送消息
143
- # 根据 target [Struct] 自动选择
144
- #
145
- # @param msg [String]
146
- # @param target [Struct]
147
- # @return [Hash]
148
- def sendMessage(msg, target)
149
- return sendGroupMessage msg, target.group_id if target.messagetype == 'group'
150
- return sendPrivateMessage msg, target.user_id if target.messagetype == 'private'
151
- end
152
-
153
- private
154
-
155
- #
156
- # 解析API返回
157
- #
158
- def parseRet(ret)
159
- return true if ret['status'] == 'ok'
160
- return false if ret['status'] == 'failed'
161
- end
162
- #
163
- # 消息解析部分
164
- #
165
- def dataParse(data)
166
- msg = JSON.parse(data)
167
- sdr = Sender.new
168
- tar = Target.new
169
- tar.time = msg['time']
170
- if msg['meta_event_type'] == 'lifecycle' && msg['sub_type'] == 'connect'
171
- @selfID = msg['self_id']
172
- Utils.log "连接成功, BotQQ: #{@selfID}"
173
- emit :logged, @selfID
174
- end
175
- Utils.log data, Logger::DEBUG if msg['meta_event_type'] != 'heartbeat' # 过滤心跳
176
- #
177
- # 函数回调
178
- #
179
- if msg.include?('echo')
180
- @queueList[msg['echo']] << msg
181
- end
182
- case msg['post_type']
183
- #
184
- # 请求事件
185
- #
186
- when 'request'
187
- case msg['request_type']
188
- when 'group'
189
- Utils.log "收到用户 #{msg['user_id']} 加群 #{msg['group_id']} 的请求 (#{msg['flag']})" if msg['sub_type'] == 'add' # 加群请求
190
- Utils.log "收到用户 #{msg['user_id']} 的加群 #{msg['group_id']} 请求 (#{msg['flag']})" if msg['sub_type'] == 'invite' # 加群邀请
191
- when 'friend' # 加好友邀请
192
- Utils.log "收到用户 #{msg['user_id']} 的好友请求 (#{msg['flag']})"
193
- end
194
- emit :request, msg['request_type'], msg
195
- #
196
- # 提醒事件
197
- #
198
- when 'notice'
199
- case msg['notice_type']
200
- when 'group_admin' # 群管理员变动
201
- Utils.log "群 #{msg['group_id']} 内 #{msg['user_id']} 成了管理员" if msg['sub_type'] == 'set' # 设置管理员
202
- Utils.log "群 #{msg['group_id']} 内 #{msg['user_id']} 没了管理员" if msg['sub_type'] == 'unset' # 取消管理员
203
- when 'group_increase' # 群成员增加
204
- Utils.log "#{msg['operator_id']} 已同意 #{msg['user_id']} 进入了群 #{msg['group_id']}" if msg['sub_type'] == 'approve' # 管理员已同意入群
205
- Utils.log "#{msg['operator_id']} 邀请 #{msg['user_id']} 进入了群 #{msg['group_id']}" if msg['sub_type'] == 'invite' # 管理员邀请入群
206
- when 'group_decrease' # 群成员减少
207
- Utils.log "被 #{msg['operator_id']} 踢出了群 #{msg['group_id']}" if msg['sub_type'] == 'kick_me' # 登录号被踢
208
- Utils.log "#{msg['user_id']} 被 #{msg['operator_id']} 踢出了群 #{msg['group_id']}" if msg['sub_type'] == 'kick' # 成员被踢
209
- Utils.log "#{msg['operator_id']} 退出了群 #{msg['group_id']}" if msg['sub_type'] == 'leave' # 主动退群
210
- when 'group_ban' # 群禁言
211
- Utils.log "群 #{msg['group_id']} 内 #{msg['user_id']} 被 #{msg['operator_id']} 禁言了 #{msg['duration']} 秒" if msg['sub_type'] == 'ban' # 禁言
212
- Utils.log "群 #{msg['group_id']} 内 #{msg['user_id']} 被 #{msg['operator_id']} 解除禁言" if msg['sub_type'] == 'lift_ban' # 解除禁言
213
- when 'friend_add' # 好友添加
214
- Utils.log "#{msg['user_id']} 成了你的好友"
215
- when 'group_recall' # 群消息撤回
216
- Utils.log "群 #{msg['group_id']} 内 #{msg['user_id']} 撤回了一条消息 (#{msg['message_id']})"
217
- when 'friend_recall' # 好友消息撤回
218
- Utils.log "好友 #{msg['user_id']} 撤回了一条消息 (#{msg['message_id']})"
219
- end
220
- emit :notice, msg['notice_type'], msg
221
-
222
- #
223
- # 消息事件
224
- #
225
- when 'message'
226
- tar.user_id = msg['user_id'] # 用户id
227
- sdr.user_id = msg['sender']['user_id'] # 用户id
228
- tar.message_id = msg['message_id'] # 消息id
229
- tar.message = msg['message'] # 消息内容
230
- tar.raw_message = msg['raw_message'] # 消息内容
231
- sdr.age = msg['sender']['age'] # 年龄
232
- sdr.nickname = msg['sender']['nickname'] # 原有用户名
233
- sdr.sex = msg['sender']['sex'] # 性别
234
- tar.messagetype = msg['message_type'] # 消息类型
235
- tar.sub_type = msg['sub_type'] # 消息子类型
236
- # 下面仅群聊
237
- tar.group_id = msg['group_id'] # 群id
238
- tar.anonymous = msg['anonymous'] # 匿名信息
239
- sdr.card = msg['sender']['card'] # 群昵称
240
- sdr.title = msg['sender']['title'] # 头衔
241
- sdr.member_role = msg['sender']['role'] # 群成员地位
242
- sdr.qqlevel = msg['sender']['level'] # 群成员等级
243
- if tar.messagetype == 'group' # 判断是否为群聊
244
- Utils.log "收到群 #{tar.group_id} 内 #{sdr.nickname}(#{tar.user_id}) 的消息: #{tar.message} (#{tar.message_id})"
245
- emit :groupMessage, tar.message, sdr, tar
246
- else
247
- Utils.log "收到好友 #{sdr.nickname}(#{tar.user_id}) 的消息: #{tar.message} (#{tar.message_id})"
248
- emit :privateMessage, tar.message, sdr, tar
249
- end
250
- emit :message, tar.message, sdr, tar
251
- end
252
- end
253
- end
254
- end
255
- end
data/lib/Bot/Utils.rb DELETED
@@ -1,119 +0,0 @@
1
- module CQHttp
2
- # 各种工具包
3
- #
4
- # Example:
5
- # CQHttp::Utils.log str, Logger::INFO
6
- class Utils
7
- # @!method stdLogger
8
- # @return [Logger] 终端Logger
9
- # @!method fileLogger
10
- # @return [Logger] 文件Logger
11
- # @!method loggerFile
12
- # @return [String] Logger文件地址
13
- attr_accessor :stdLogger, :fileLogger, :loggerFile
14
- class << self
15
-
16
- # 初始化日志
17
- #
18
- # @param loggerFile [String]
19
- def initLogger(loggerFile=nil)
20
- @loggerFile = loggerFile
21
- @stdLogger = setLogger(Logger.new(STDOUT))
22
- @fileLogger = setLogger(Logger.new(@loggerFile, 'daily')) if @loggerFile
23
- end
24
-
25
- # 设置日志等级
26
- #
27
- # @param loggerLevel [String]
28
- def setLoggerLevel(loggerLevel)
29
- @stdLogger.level = loggerLevel
30
- @fileLogger.level = loggerLevel if @loggerFile
31
- end
32
-
33
- # 输出日志
34
- #
35
- # @param str [String]
36
- # @param severity [Logger::INFO, Logger::DEBUG, Logger::WARN, Logger::ERROR]
37
- # @param app [String]
38
- def log(str, severity=Logger::INFO, app="RUBY-CQHTTP")
39
- @stdLogger.log(severity, str, app)
40
- @fileLogger.log(severity, str, app) if @loggerFile
41
- end
42
-
43
- # post发包
44
- #
45
- # @param url [URI]
46
- # @param ret [String]
47
- # @return [String]
48
- def httpPost(url, ret)
49
- req = Net::HTTP::Post.new(url.path, { 'Content-Type' => 'application/json' })
50
- req.body = ret
51
- res = Net::HTTP.start(url.hostname, url.port) do |http|
52
- http.request(req)
53
- end
54
- res.body
55
- end
56
- alias post httpPost
57
-
58
- # 消息转义
59
- # &amp; -> &
60
- # &#91; -> [
61
- # &#93; -> ]
62
- #
63
- # @param msg [String]
64
- # @return [String]
65
- def msg_change(msg)
66
- msg.gsub!('&amp;','&')
67
- msg.gsub!('&#91;','[')
68
- msg.gsub!('&#93;',']')
69
- msg
70
- end
71
-
72
- # 消息反转义
73
- # & -> &amp;
74
- # [ -> &#91;
75
- # ] -> &#93;
76
- #
77
- # @param msg [String]
78
- # @return [String]
79
- def msg_change!(msg)
80
- msg.gsub!('&','&amp;')
81
- msg.gsub!('[','&#91;')
82
- msg.gsub!(']','&#93;')
83
- msg
84
- end
85
-
86
- # CQ码解析
87
- #
88
- # @param cqmsg [String]
89
- # @return [Hash]
90
- def cq_parse(cqmsg)
91
- cqary = []
92
- cqmsg.scan(/\[CQ:(.*?),(.*?)\]/m).each do |matches|
93
- cqcode = { type: matches[0], data: {} }
94
- matches[1].split(',').each do |arg|
95
- args = arg.split('=')
96
- cqcode[:data][args[0].to_sym] = args[1]
97
- end
98
- cqary << cqcode
99
- end
100
- cqary
101
- end
102
-
103
- private
104
-
105
- # 设置logger
106
- def setLogger(logger)
107
- logger.level = 'INFO'
108
- logger.formatter = proc do |severity, datetime, progname, msg|
109
- if progname == nil
110
- "[#{datetime.strftime('%Y-%m-%d %H:%M:%S')}][#{severity}]: #{msg.to_s.gsub(/\n/,'\n').gsub(/\r/,'\r') }\n"
111
- else
112
- "[#{datetime.strftime('%Y-%m-%d %H:%M:%S')}][#{progname}][#{severity}]: #{msg.to_s.gsub(/\n/,'\n').gsub(/\r/,'\r') }\n"
113
- end
114
- end
115
- logger
116
- end
117
- end
118
- end
119
- end
data/lib/ruby-cqhttp.rb DELETED
@@ -1,17 +0,0 @@
1
- require 'faye/websocket'
2
- require 'eventmachine'
3
- require 'json'
4
- require 'event_emitter'
5
- require 'net/http'
6
- require 'uri/ws'
7
- require 'uri'
8
- require 'logger'
9
-
10
- # 一个基于 OneBot 标准的 QQ 机器人框架
11
- module CQHttp
12
- autoload :Bot, File.expand_path('Bot/Bot', __dir__)
13
- autoload :Api, File.expand_path('Bot/Api', __dir__)
14
- autoload :Utils, File.expand_path('Bot/Utils', __dir__)
15
- end
16
-
17
- CQHttp::Utils.initLogger
data/ruby-cqhttp.gemspec DELETED
@@ -1,24 +0,0 @@
1
- lib = File.expand_path('lib', __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
-
4
- Gem::Specification.new do |s|
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")
15
- s.require_paths = ['lib']
16
- s.required_ruby_version = '>= 2.7.0'
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'
24
- end