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.
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