rubirai 0.0.3.pre.a1 → 0.2.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.
- checksums.yaml +4 -4
- data/.github/workflows/docs.yml +1 -1
- data/.github/workflows/package.yml +0 -1
- data/.github/workflows/pull_request.yml +3 -1
- data/README.md +27 -2
- data/lib/rubirai/auth.rb +15 -12
- data/lib/rubirai/events/event.rb +22 -16
- data/lib/rubirai/events/message_events.rb +1 -1
- data/lib/rubirai/listener.rb +1 -1
- data/lib/rubirai/listing.rb +3 -3
- data/lib/rubirai/message.rb +21 -28
- data/lib/rubirai/messages/interpolation.rb +115 -0
- data/lib/rubirai/messages/message.rb +215 -21
- data/lib/rubirai/messages/message_chain.rb +21 -10
- data/lib/rubirai/objects/group_info.rb +5 -4
- data/lib/rubirai/utils.rb +10 -0
- data/lib/rubirai/version.rb +2 -2
- data/lib/rubirai.rb +18 -7
- data/spec/auth_spec.rb +12 -12
- data/spec/events/event_spec.rb +1 -0
- data/spec/message_spec.rb +45 -1
- data/spec/messages/interpolation_spec.rb +64 -0
- data/spec/spec_helper.rb +4 -4
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f41f579f9ae1486c4a8f5af2e12e7e98e2aab20b880b9d2b1781eb57f480c3b
|
4
|
+
data.tar.gz: 2044c0aabd41caba57890b30b1951e0440046201e1b4eaa1f91fc766ae404e1a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c34f19d099e6f2d85e403e93d9c03b82b5ad9325f26f7de0714e517b73d0ec041de372bf534bbffa34aef342394411012dd1cbf78da2a3afac87409006a547b7
|
7
|
+
data.tar.gz: 8392b2ea57dc0eb3df290a4e2b357bc184102879904fb38bbd5e9ce60bd7071b9be686fad559aff5b9ef4b8711e93bf205949fc9605991c661429425d3b31ebb
|
data/.github/workflows/docs.yml
CHANGED
data/README.md
CHANGED
@@ -11,6 +11,28 @@ A light-weight Mirai QQ bot http interface lib for Ruby.
|
|
11
11
|
|
12
12
|
[中文][wiki] | [Rubydocs][rubydocs]
|
13
13
|
|
14
|
+
## Description
|
15
|
+
|
16
|
+
This library is designed specifically for integration with [mirai-api-http].
|
17
|
+
[Mirai][mirai] is a QQ bot framework. The relationship is like this:
|
18
|
+
|
19
|
+
```
|
20
|
+
mirai <-jvm-> mirai-console <-plugin-> mirai-api-http <-http-> rubirai
|
21
|
+
```
|
22
|
+
|
23
|
+
[mirai-api-http]: https://github.com/project-mirai/mirai-api-http
|
24
|
+
[mirai]: https://github.com/mamoe/mirai
|
25
|
+
|
26
|
+
## Prerequisite
|
27
|
+
|
28
|
+
Install [mirai-api-http] and configure its `setting.yml` file.
|
29
|
+
|
30
|
+
Now its easier to enable `singleMode` if you have only one account
|
31
|
+
in the mirai console.
|
32
|
+
|
33
|
+
Note that you **must** enable Http Adapter with configuration of
|
34
|
+
`http` under `adapterSettings`. More mode support to come.
|
35
|
+
|
14
36
|
## Usage
|
15
37
|
|
16
38
|
First, download the package using `gem`. In your `Gemfile`, add
|
@@ -26,7 +48,7 @@ require 'rubirai'
|
|
26
48
|
# assuming your mirai http api address and port
|
27
49
|
# are 127.0.0.1 and 8080
|
28
50
|
bot = Rubirai::Bot.new('127.0.0.1', '8080')
|
29
|
-
# qq and
|
51
|
+
# qq and verify key
|
30
52
|
bot.login 1145141919, 'ikisugi_key'
|
31
53
|
|
32
54
|
# Add a listener function
|
@@ -53,10 +75,13 @@ gem install rubirai
|
|
53
75
|
- [中文 Wiki][wiki]
|
54
76
|
- [Docs][rubydocs]
|
55
77
|
|
56
|
-
|
57
78
|
## License
|
79
|
+
|
80
|
+
[AGPL-3.0 License][license]
|
81
|
+
|
58
82
|
[](https://app.fossa.com/projects/git%2Bgithub.com%2FShimogawa%2Frubirai?ref=badge_large)
|
59
83
|
|
60
84
|
|
61
85
|
[wiki]: https://github.com/Shimogawa/rubirai/wiki
|
62
86
|
[rubydocs]: https://www.rebuild.moe/rubirai/
|
87
|
+
[license]: LICENSE
|
data/lib/rubirai/auth.rb
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
module Rubirai
|
4
4
|
class Bot
|
5
|
-
# Start
|
6
|
-
# @param
|
5
|
+
# Start verification. Will store the session.
|
6
|
+
# @param verify_key [String] the auth key defined in config file
|
7
7
|
# @return [String] the session key which will also be stored in the bot
|
8
|
-
def
|
9
|
-
v = call :post, '/
|
8
|
+
def verify(verify_key)
|
9
|
+
v = call :post, '/verify', json: { "verifyKey": verify_key }
|
10
10
|
@session = v['session']
|
11
11
|
end
|
12
12
|
|
@@ -14,11 +14,11 @@ module Rubirai
|
|
14
14
|
# @param qq [String, Integer] qq id
|
15
15
|
# @param session [String, nil] the session key. Set to `nil` will use the saved credentials.
|
16
16
|
# @return [void]
|
17
|
-
def
|
17
|
+
def bind(qq, session = nil)
|
18
18
|
check qq, session
|
19
19
|
|
20
|
-
call :post, '/
|
21
|
-
@session
|
20
|
+
call :post, '/bind', json: { "sessionKey": @session || session, "qq": qq.to_i }
|
21
|
+
@session ||= session
|
22
22
|
@qq = qq
|
23
23
|
nil
|
24
24
|
end
|
@@ -42,13 +42,16 @@ module Rubirai
|
|
42
42
|
# Log you in.
|
43
43
|
#
|
44
44
|
# @param qq [String, Integer] qq id
|
45
|
-
# @param
|
45
|
+
# @param verify_key [String] the auth key set in the settings file for mirai-api-http.
|
46
|
+
# @param single_mode [Boolean] if to skip binding (need to enable `singeMode` for
|
47
|
+
# mirai-http-api)
|
46
48
|
# @return [void]
|
47
|
-
# @see #
|
49
|
+
# @see #bind
|
48
50
|
# @see #verify
|
49
|
-
def login(qq,
|
50
|
-
|
51
|
-
|
51
|
+
def login(qq, verify_key, single_mode: false)
|
52
|
+
verify verify_key
|
53
|
+
single_mode or bind(qq)
|
54
|
+
nil
|
52
55
|
end
|
53
56
|
|
54
57
|
alias connect login
|
data/lib/rubirai/events/event.rb
CHANGED
@@ -58,22 +58,7 @@ module Rubirai
|
|
58
58
|
attr_keys.each do |k|
|
59
59
|
k2 = k.to_s.snake_to_camel(lower: true)
|
60
60
|
val = hash[k2]
|
61
|
-
val =
|
62
|
-
when 'group'
|
63
|
-
Group.new val, bot
|
64
|
-
when 'operator', 'member'
|
65
|
-
GroupUser.new val, bot
|
66
|
-
when 'sender'
|
67
|
-
if val.key? 'group'
|
68
|
-
GroupUser.new val, bot
|
69
|
-
else
|
70
|
-
User.new val, bot
|
71
|
-
end
|
72
|
-
when 'messageChain'
|
73
|
-
MessageChain.new bot, val
|
74
|
-
else
|
75
|
-
val
|
76
|
-
end
|
61
|
+
val = parse_val_from_key k2, val, bot
|
77
62
|
instance_variable_set("@#{k}", val)
|
78
63
|
end
|
79
64
|
end
|
@@ -107,6 +92,27 @@ module Rubirai
|
|
107
92
|
@raw = hash
|
108
93
|
@bot = bot
|
109
94
|
end
|
95
|
+
|
96
|
+
protected
|
97
|
+
|
98
|
+
def parse_val_from_key(key, val, bot)
|
99
|
+
case key
|
100
|
+
when 'group'
|
101
|
+
Group.new val, bot
|
102
|
+
when 'operator', 'member'
|
103
|
+
GroupUser.new val, bot
|
104
|
+
when 'sender'
|
105
|
+
if val.key? 'group'
|
106
|
+
GroupUser.new val, bot
|
107
|
+
else
|
108
|
+
User.new val, bot
|
109
|
+
end
|
110
|
+
when 'messageChain'
|
111
|
+
MessageChain.new bot, val
|
112
|
+
else
|
113
|
+
val
|
114
|
+
end
|
115
|
+
end
|
110
116
|
end
|
111
117
|
end
|
112
118
|
|
data/lib/rubirai/listener.rb
CHANGED
@@ -7,7 +7,7 @@ module Rubirai
|
|
7
7
|
class Bot
|
8
8
|
# Start to listen for events
|
9
9
|
#
|
10
|
-
# @param interval [
|
10
|
+
# @param interval [Integer, Float] the interval to fetch events in seconds.
|
11
11
|
# @param is_blocking [Boolean] if the listen thread should block the current thread
|
12
12
|
# @param ignore_error [Boolean] if errors should generate error events (see {RubiraiErrorEvent})
|
13
13
|
# @return [void]
|
data/lib/rubirai/listing.rb
CHANGED
@@ -11,7 +11,7 @@ module Rubirai
|
|
11
11
|
resp = call :get, '/friendList', params: {
|
12
12
|
sessionKey: @session
|
13
13
|
}
|
14
|
-
resp.map { |friend| User.new(friend, self) }
|
14
|
+
resp['data'].map { |friend| User.new(friend, self) }
|
15
15
|
end
|
16
16
|
|
17
17
|
# Get group list of the bot
|
@@ -20,7 +20,7 @@ module Rubirai
|
|
20
20
|
resp = call :get, '/groupList', params: {
|
21
21
|
sessionKey: @session
|
22
22
|
}
|
23
|
-
resp.map { |group| Group.new(group, self) }
|
23
|
+
resp['data'].map { |group| Group.new(group, self) }
|
24
24
|
end
|
25
25
|
|
26
26
|
# Get member list of a group
|
@@ -31,7 +31,7 @@ module Rubirai
|
|
31
31
|
sessionKey: @session,
|
32
32
|
target: group_id
|
33
33
|
}
|
34
|
-
resp.map { |member| GroupUser.new(member, self) }
|
34
|
+
resp['data'].map { |member| GroupUser.new(member, self) }
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
data/lib/rubirai/message.rb
CHANGED
@@ -10,15 +10,17 @@ module Rubirai
|
|
10
10
|
# @param target_qq [Integer] target qq id
|
11
11
|
# @param group_id [Integer] group id
|
12
12
|
# @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain, can be any type
|
13
|
+
# @param quote [NilClass, Integer] the message id to quote, nil for not quote
|
13
14
|
# @return [Integer] message id
|
14
|
-
def send_temp_msg(target_qq, group_id, *msgs)
|
15
|
+
def send_temp_msg(target_qq, group_id, *msgs, quote: nil)
|
15
16
|
chain = Rubirai::MessageChain.make(*msgs, bot: self)
|
16
17
|
resp = call :post, '/sendTempMessage', json: {
|
17
18
|
sessionKey: @session,
|
18
19
|
qq: target_qq.to_i,
|
19
20
|
group: group_id.to_i,
|
21
|
+
quote: quote,
|
20
22
|
messageChain: chain.to_a
|
21
|
-
}
|
23
|
+
}.compact
|
22
24
|
resp['messageId']
|
23
25
|
end
|
24
26
|
|
@@ -27,15 +29,17 @@ module Rubirai
|
|
27
29
|
# @param type [Symbol, String] options: [group, friend]
|
28
30
|
# @param target_id [Integer] target qq/group id
|
29
31
|
# @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain, can be any type
|
32
|
+
# @param quote [NilClass, Integer] the message id to quote, nil for not quote
|
30
33
|
# @return [Integer] message id
|
31
|
-
def send_msg(type, target_id, *msgs)
|
34
|
+
def send_msg(type, target_id, *msgs, quote: nil)
|
32
35
|
self.class.ensure_type_in type, 'group', 'friend'
|
33
36
|
chain = Rubirai::MessageChain.make(*msgs, bot: self)
|
34
37
|
resp = call :post, "/send#{type.to_s.snake_to_camel}Message", json: {
|
35
38
|
sessionKey: @session,
|
36
39
|
target: target_id.to_i,
|
40
|
+
quote: quote,
|
37
41
|
messageChain: chain.to_a
|
38
|
-
}
|
42
|
+
}.compact
|
39
43
|
resp['messageId']
|
40
44
|
end
|
41
45
|
|
@@ -43,25 +47,28 @@ module Rubirai
|
|
43
47
|
#
|
44
48
|
# @param target_qq [Integer] target qq id
|
45
49
|
# @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain, can be any type
|
50
|
+
# @param quote [NilClass, Integer] the message id to quote, nil for not quote
|
46
51
|
# @return [Integer] message id
|
47
|
-
def send_friend_msg(target_qq, *msgs)
|
48
|
-
send_msg :friend, target_qq, *msgs
|
52
|
+
def send_friend_msg(target_qq, *msgs, quote: nil)
|
53
|
+
send_msg :friend, target_qq, *msgs, quote: quote
|
49
54
|
end
|
50
55
|
|
51
56
|
# Send group message
|
52
57
|
#
|
53
58
|
# @param target_group_id [Integer] group id
|
54
59
|
# @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain, can be any type
|
60
|
+
# @param quote [NilClass, Integer] the message id to quote, nil for not quote
|
55
61
|
# @return [Integer] message id
|
56
|
-
def send_group_msg(target_group_id, *msgs)
|
57
|
-
send_msg :group, target_group_id, *msgs
|
62
|
+
def send_group_msg(target_group_id, *msgs, quote: nil)
|
63
|
+
send_msg :group, target_group_id, *msgs, quote: quote
|
58
64
|
end
|
59
65
|
|
60
66
|
# Recall a message
|
61
67
|
#
|
62
|
-
# @param msg_id [Integer] message id
|
68
|
+
# @param msg_id [Integer, Rubirai::MessageChain] message id
|
63
69
|
# @return [void]
|
64
70
|
def recall(msg_id)
|
71
|
+
msg_id = msg_id.id if msg_id.is_a? Rubirai::MessageChain
|
65
72
|
call :post, '/recall', json: {
|
66
73
|
sessionKey: @session,
|
67
74
|
target: msg_id
|
@@ -114,34 +121,20 @@ module Rubirai
|
|
114
121
|
#
|
115
122
|
# @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain
|
116
123
|
# @param quote [Boolean] if to quote the original message
|
117
|
-
# @return [
|
124
|
+
# @return [Integer] message id
|
118
125
|
def respond(*msgs, quote: false)
|
119
126
|
check_bot
|
120
|
-
|
127
|
+
quote_id = quote ? (@message_chain.id || nil) : nil
|
121
128
|
case self
|
122
129
|
when FriendMessageEvent
|
123
|
-
@bot.send_friend_msg(@sender.id, *msgs)
|
130
|
+
@bot.send_friend_msg(@sender.id, *msgs, quote: quote_id)
|
124
131
|
when GroupMessageEvent
|
125
|
-
@bot.send_group_msg(@sender.group.id, *msgs)
|
132
|
+
@bot.send_group_msg(@sender.group.id, *msgs, quote: quote_id)
|
126
133
|
when TempMessageEvent
|
127
|
-
@bot.send_temp_msg(@sender.id, @sender.group.id, *msgs)
|
134
|
+
@bot.send_temp_msg(@sender.id, @sender.group.id, *msgs, quote: quote_id)
|
128
135
|
else
|
129
136
|
raise 'undefined error'
|
130
137
|
end
|
131
|
-
nil
|
132
|
-
end
|
133
|
-
|
134
|
-
# Generates a quote message from this event
|
135
|
-
#
|
136
|
-
# @return [QuoteMessage] the quote message
|
137
|
-
def gen_quote
|
138
|
-
QuoteMessage.from(
|
139
|
-
id: @message_chain.id,
|
140
|
-
group_id: @sender.is_a?(GroupUser) ? @sender.group.id : 0,
|
141
|
-
sender_id: @sender.id,
|
142
|
-
target_id: @sender.is_a?(GroupUser) ? @sender.group.id : @bot.qq,
|
143
|
-
origin: @message_chain
|
144
|
-
)
|
145
138
|
end
|
146
139
|
|
147
140
|
private
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubirai/utils'
|
4
|
+
|
5
|
+
module Rubirai
|
6
|
+
# @!attribute [r] has_interpolation
|
7
|
+
# @return [Boolean] if this message chain has interpolation called by {#interpolated_str}
|
8
|
+
class MessageChain
|
9
|
+
attr_reader :has_interpolation
|
10
|
+
|
11
|
+
# Convert the message chain to an interpolated string.
|
12
|
+
#
|
13
|
+
# @return [String]
|
14
|
+
def interpolated_str
|
15
|
+
return @interpolated_str if @has_interpolation
|
16
|
+
@interpolated_str = _gen_interp_str
|
17
|
+
@has_interpolation = true
|
18
|
+
@interpolated_str
|
19
|
+
end
|
20
|
+
|
21
|
+
# Get the interpolated object by given id
|
22
|
+
#
|
23
|
+
# @param obj_id [String] the object id
|
24
|
+
# @return [Message, nil] the message. `nil` if `obj_id` is malformed or not found.
|
25
|
+
def get_object(obj_id)
|
26
|
+
_get_object(obj_id)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Get a new chain from interpolated string generated from the original message chain.
|
30
|
+
# The given interpolated string can be a substring of original one so that elements
|
31
|
+
# can be extracted easily.
|
32
|
+
#
|
33
|
+
# @param str [String] the interpolated string
|
34
|
+
# @return [MessageChain] the message chain constructed
|
35
|
+
def chain_from_interpolated(str)
|
36
|
+
_interpolate_with_objects(str)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
OBJ_INTERP_CHAR = '%'
|
42
|
+
OBJ_INTERP_LEN = 6
|
43
|
+
|
44
|
+
def _gen_interp_str
|
45
|
+
result = +''
|
46
|
+
@messages.each do |msg|
|
47
|
+
result << case msg
|
48
|
+
when PlainMessage
|
49
|
+
_transform_plain_txt(msg.text)
|
50
|
+
else
|
51
|
+
_transform_object(msg)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
def _transform_plain_txt(str)
|
58
|
+
str.gsub(OBJ_INTERP_CHAR, OBJ_INTERP_CHAR * 2)
|
59
|
+
end
|
60
|
+
|
61
|
+
def _transform_object(obj)
|
62
|
+
obj_id = Utils.random_str(OBJ_INTERP_LEN)
|
63
|
+
obj_id = Utils.random_str(OBJ_INTERP_LEN) while @ipl_objs_map.include?(obj_id)
|
64
|
+
@ipl_objs_map[obj_id] = obj
|
65
|
+
"#{OBJ_INTERP_CHAR}#{obj_id}#{OBJ_INTERP_CHAR}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def _get_object(obj_id)
|
69
|
+
return nil if obj_id.length != OBJ_INTERP_LEN && obj_id.length != (OBJ_INTERP_LEN + 2)
|
70
|
+
return @ipl_objs_map[obj_id] if obj_id.length == OBJ_INTERP_LEN
|
71
|
+
return nil if obj_id[0] != OBJ_INTERP_CHAR || obj_id[-1] != OBJ_INTERP_CHAR
|
72
|
+
|
73
|
+
@ipl_objs_map[obj_id[1...-1]]
|
74
|
+
end
|
75
|
+
|
76
|
+
# @private
|
77
|
+
# @param str [String]
|
78
|
+
def _interpolate_with_objects(str)
|
79
|
+
sb = +''
|
80
|
+
result = MessageChain.new(bot)
|
81
|
+
i = 0
|
82
|
+
while i < str.length
|
83
|
+
if i == str.length - 1
|
84
|
+
sb << str[i]
|
85
|
+
break
|
86
|
+
end
|
87
|
+
|
88
|
+
if str[i] != OBJ_INTERP_CHAR
|
89
|
+
sb << str[i]
|
90
|
+
i += 1
|
91
|
+
next
|
92
|
+
end
|
93
|
+
|
94
|
+
if str[i + 1] == OBJ_INTERP_CHAR
|
95
|
+
sb << OBJ_INTERP_CHAR
|
96
|
+
i += 1
|
97
|
+
else
|
98
|
+
result.append PlainMessage.from(text: sb) unless sb.empty?
|
99
|
+
sb = str[i...i + OBJ_INTERP_LEN + 2]
|
100
|
+
obj = _get_object(sb)
|
101
|
+
i += OBJ_INTERP_LEN + 1
|
102
|
+
unless obj.nil?
|
103
|
+
result.append obj
|
104
|
+
sb = +''
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
i += 1
|
109
|
+
end
|
110
|
+
|
111
|
+
result.append PlainMessage.from(text: sb) unless sb.nil? || sb.empty?
|
112
|
+
result
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -2,25 +2,75 @@
|
|
2
2
|
|
3
3
|
require 'rubirai/utils'
|
4
4
|
|
5
|
+
# @!method self.AtMessage(**kwargs)
|
6
|
+
# Form an {Rubirai::AtMessage}. The `display` option has no effect when
|
7
|
+
# sending at messages.
|
8
|
+
# @option kwargs [Integer] :target the target id
|
9
|
+
# @return [Rubirai::AtMessage] the message object
|
10
|
+
# @see Rubirai::AtMessage.from
|
11
|
+
# @!method self.QuoteMessage(**kwargs)
|
12
|
+
# Form a {Rubirai::QuoteMessage}.
|
13
|
+
# @return [Rubirai::QuoteMessage] the message object
|
14
|
+
# @see Rubirai::QuoteMessage.from
|
15
|
+
# @!method self.AtAllMessage()
|
16
|
+
# Form an {Rubirai::AtAllMessage}.
|
17
|
+
# @return [Rubirai::AtAllMessage] the message object
|
18
|
+
# @see Rubirai::AtAllMessage.from
|
19
|
+
# @!method self.FaceMessage(**kwargs)
|
20
|
+
# Form a {Rubirai::FaceMessage}. Only needs to give one of the two arguments.
|
21
|
+
# @option kwargs [Integer] :face_id the face id (high priority)
|
22
|
+
# @option kwargs [String] :name the face's name (low priority)
|
23
|
+
# @return [Rubirai::FaceMessage] the message object
|
24
|
+
# @see Rubirai::FaceMessage.from
|
25
|
+
# @!method self.PlainMessage(**kwargs)
|
26
|
+
# @option kwargs [String] :text the plain text
|
27
|
+
# @return [Rubirai::PlainMessage] the message object
|
28
|
+
# @see Rubirai::PlainMessage.from
|
29
|
+
# @!method self.ImageMessage(**kwargs)
|
30
|
+
# Form an {Rubirai::ImageMessage}. Only needs to give one of the three arguments.
|
31
|
+
# @option kwargs [String] :image_id the image id
|
32
|
+
# @option kwargs [String] :url the url of the image
|
33
|
+
# @option kwargs [String] :path the local path of the image
|
34
|
+
# @return [Rubirai::ImageMessage] the message object
|
35
|
+
# @see Rubirai::ImageMessage.from
|
36
|
+
# @!method self.FlashImageMessage(**kwargs)
|
37
|
+
# Form a {Rubirai::FlashImageMessage}. Only needs to give one of the three arguments.
|
38
|
+
# @option kwargs [String] :image_id the image id
|
39
|
+
# @option kwargs [String] :url the url of the image
|
40
|
+
# @option kwargs [String] :path the local path of the image
|
41
|
+
# @return [Rubirai::FlashImageMessage] the message object
|
42
|
+
# @see Rubirai::FlashImageMessage.from
|
43
|
+
# @!method self.VoiceMessage(**kwargs)
|
44
|
+
# Form a {Rubirai::VoiceMessage}. Only needs to give one of the three arguments.
|
45
|
+
# @option kwargs [String] :voice_id the voice id
|
46
|
+
# @option kwargs [String] :url the url of the voice
|
47
|
+
# @option kwargs [String] :path the local path of the voice
|
48
|
+
# @return [Rubirai::VoiceMessage] the message object
|
49
|
+
# @see Rubirai::VoiceMessage.from
|
50
|
+
# @!method self.XmlMessage(**kwargs)
|
51
|
+
# Form a {Rubirai::XmlMessage}.
|
52
|
+
# @option kwargs [String] :xml the xml body
|
53
|
+
# @return [Rubirai::XmlMessage] the message object
|
54
|
+
# @see Rubirai::XmlMessage.from
|
55
|
+
# @!method self.JsonMessage(**kwargs)
|
56
|
+
# Form a {Rubirai::JsonMessage}.
|
57
|
+
# @option kwargs [String] :json the json body
|
58
|
+
# @return [Rubirai::JsonMessage] the message object
|
59
|
+
# @see Rubirai::JsonMessage.from
|
60
|
+
# @!method self.AppMessage(**kwargs)
|
61
|
+
# Form an {Rubirai::AppMessage}.
|
62
|
+
# @option kwargs [String] :content the app body
|
63
|
+
# @return [Rubirai::AppMessage] the message object
|
64
|
+
# @see Rubirai::AppMessage.from
|
65
|
+
# @!method self.PokeMessage(**kwargs)
|
66
|
+
# Form a {Rubirai::PokeMessage}.
|
67
|
+
# @option kwargs [String] :name the poke name
|
68
|
+
# @return [Rubirai::PokeMessage] the message object
|
69
|
+
# @see Rubirai::PokeMessage.from
|
5
70
|
module Rubirai
|
6
71
|
# The message abstract class.
|
7
72
|
#
|
8
73
|
# @abstract
|
9
|
-
# @!method self.AtMessage(**kwargs)
|
10
|
-
# @param kwargs [Hash{Symbol => Object}] arguments
|
11
|
-
# @return [Rubirai::AtMessage]
|
12
|
-
# @!method self.QuoteMessage(**kwargs)
|
13
|
-
# @param kwargs [Hash{Symbol => Object}] arguments
|
14
|
-
# @return [Rubirai::QuoteMessage]
|
15
|
-
# @!method self.AtAllMessage(**kwargs)
|
16
|
-
# @param kwargs [Hash{Symbol => Object}] arguments
|
17
|
-
# @return [Rubirai::AtAllMessage]
|
18
|
-
# @!method self.FaceMessage(**kwargs)
|
19
|
-
# @param kwargs [Hash{Symbol => Object}] arguments
|
20
|
-
# @return [Rubirai::FaceMessage]
|
21
|
-
# @!method self.PlainMessage(**kwargs)
|
22
|
-
# @option text [String] the plain text
|
23
|
-
# @return [Rubirai::PlainMessage]
|
24
74
|
class Message
|
25
75
|
# @!attribute [r] bot
|
26
76
|
# @return [Bot] the bot
|
@@ -30,7 +80,7 @@ module Rubirai
|
|
30
80
|
|
31
81
|
# Objects to {Rubirai::Message}
|
32
82
|
#
|
33
|
-
# @param msg [Rubirai::Message, Hash, Object] the object to transform to a message
|
83
|
+
# @param msg [Rubirai::Message, Hash{String => Object}, Object] the object to transform to a message
|
34
84
|
# @return [Rubirai::Message] the message
|
35
85
|
def self.to_message(msg, bot = nil)
|
36
86
|
# noinspection RubyYardReturnMatch
|
@@ -150,6 +200,10 @@ module Rubirai
|
|
150
200
|
end
|
151
201
|
end
|
152
202
|
|
203
|
+
# {include:Rubirai::Message.to_message}
|
204
|
+
# @param obj [Message, Hash{String => Object}, Object] the object
|
205
|
+
# @return [Message] the message
|
206
|
+
# @see Rubirai::Message.to_message
|
153
207
|
def self.Message(obj, bot = nil)
|
154
208
|
Message.to_message obj, bot
|
155
209
|
end
|
@@ -185,7 +239,9 @@ module Rubirai
|
|
185
239
|
# @return [Integer] the original receiver's (group or user) id
|
186
240
|
# @!attribute [r] origin
|
187
241
|
# @return [MessageChain] the original message chain
|
188
|
-
|
242
|
+
# @!method from(**kwargs)
|
243
|
+
# Form a {QuoteMessage}.
|
244
|
+
set_message :Quote, :id, :group_id, :sender_id, :target_id, :origin, :origin_raw
|
189
245
|
|
190
246
|
# @private
|
191
247
|
def initialize(hash, bot = nil)
|
@@ -195,6 +251,18 @@ module Rubirai
|
|
195
251
|
@sender_id = hash['senderId']
|
196
252
|
@target_id = hash['targetId']
|
197
253
|
@origin = MessageChain.make(*hash['origin'], bot: bot)
|
254
|
+
@origin_raw = hash['origin']
|
255
|
+
end
|
256
|
+
|
257
|
+
def to_h
|
258
|
+
{
|
259
|
+
'type' => 'Quote',
|
260
|
+
'id' => @id,
|
261
|
+
'groupId' => @group_id,
|
262
|
+
'senderId' => @sender_id,
|
263
|
+
'targetId' => @target_id,
|
264
|
+
'origin' => @origin_raw || @origin.to_a
|
265
|
+
}.compact
|
198
266
|
end
|
199
267
|
end
|
200
268
|
|
@@ -205,15 +273,16 @@ module Rubirai
|
|
205
273
|
# @!attribute [r] display
|
206
274
|
# @return [String] the displayed name (not used when sending)
|
207
275
|
# @!method from(**kwargs)
|
208
|
-
#
|
276
|
+
# Form an {AtMessage}. The `display` option has no effect when
|
277
|
+
# sending at messages.
|
278
|
+
# @option kwargs [Integer] :target the target id
|
209
279
|
# @return [AtMessage] the message object
|
210
280
|
set_message :At, :target, :display
|
211
281
|
end
|
212
282
|
|
213
283
|
# The At All message type
|
214
284
|
class AtAllMessage < Message
|
215
|
-
# @!method from(
|
216
|
-
# @param kwargs [Hash{Symbol => Object}] the fields to set
|
285
|
+
# @!method from()
|
217
286
|
# @return [AtAllMessage] the message object
|
218
287
|
set_message :AtAll
|
219
288
|
end
|
@@ -224,6 +293,12 @@ module Rubirai
|
|
224
293
|
# @return [Integer] the face's id
|
225
294
|
# @!attribute [r] name
|
226
295
|
# @return [String, nil] the face's name
|
296
|
+
# @!method from(**kwargs)
|
297
|
+
# Form a {Rubirai::FaceMessage}. Only needs to give one of the two arguments.
|
298
|
+
# @option kwargs [Integer] :face_id the face id (high priority)
|
299
|
+
# @option kwargs [String] :name the face's name (low priority)
|
300
|
+
# @return [Rubirai::FaceMessage] the message object
|
301
|
+
# @!scope class
|
227
302
|
set_message :Face, :face_id, :name
|
228
303
|
end
|
229
304
|
|
@@ -231,6 +306,10 @@ module Rubirai
|
|
231
306
|
class PlainMessage < Message
|
232
307
|
# @!attribute [r] text
|
233
308
|
# @return [String] the text
|
309
|
+
# @!method from(**kwargs)
|
310
|
+
# @option kwargs [String] :text the plain text
|
311
|
+
# @return [PlainMessage] the message object
|
312
|
+
# @!scope class
|
234
313
|
set_message :Plain, :text
|
235
314
|
end
|
236
315
|
|
@@ -238,21 +317,54 @@ module Rubirai
|
|
238
317
|
# Only one out of the three fields is needed to form the message.
|
239
318
|
class ImageMessage < Message
|
240
319
|
# @!attribute [r] image_id
|
241
|
-
# @return [
|
320
|
+
# @return [String, nil] the image id from mirai
|
242
321
|
# @!attribute [r] url
|
243
322
|
# @return [String, nil] the url of the image
|
244
323
|
# @!attribute [r] path
|
245
324
|
# @return [String, nil] the local path of the image
|
325
|
+
# @!method from(**kwargs)
|
326
|
+
# Form an {Rubirai::ImageMessage}. Only needs to give one of the three arguments.
|
327
|
+
# @option kwargs [String] :image_id the image id
|
328
|
+
# @option kwargs [String] :url the url of the image
|
329
|
+
# @option kwargs [String] :path the local path of the image
|
330
|
+
# @return [Rubirai::ImageMessage] the message object
|
331
|
+
# @!scope class
|
246
332
|
set_message :Image, :image_id, :url, :path
|
247
333
|
end
|
248
334
|
|
249
335
|
# The flash image message type
|
250
336
|
class FlashImageMessage < Message
|
337
|
+
# @!attribute [r] image_id
|
338
|
+
# @return [String, nil] the image id from mirai
|
339
|
+
# @!attribute [r] url
|
340
|
+
# @return [String, nil] the url of the image
|
341
|
+
# @!attribute [r] path
|
342
|
+
# @return [String, nil] the local path of the image
|
343
|
+
# @!method from(**kwargs)
|
344
|
+
# Form a {Rubirai::FlashImageMessage}. Only needs to give one of the three arguments.
|
345
|
+
# @option kwargs [String] :image_id the image id
|
346
|
+
# @option kwargs [String] :url the url of the image
|
347
|
+
# @option kwargs [String] :path the local path of the image
|
348
|
+
# @return [Rubirai::FlashImageMessage] the message object
|
349
|
+
# @!scope class
|
251
350
|
set_message :FlashImage, :image_id, :url, :path
|
252
351
|
end
|
253
352
|
|
254
353
|
# The voice message type
|
255
354
|
class VoiceMessage < Message
|
355
|
+
# @!attribute [r] voice_id
|
356
|
+
# @return [String, nil] the voice id from mirai
|
357
|
+
# @!attribute [r] url
|
358
|
+
# @return [String, nil] the url of the voice
|
359
|
+
# @!attribute [r] path
|
360
|
+
# @return [String, nil] the local path of the voice
|
361
|
+
# @!method from(**kwargs)
|
362
|
+
# Form a {Rubirai::VoiceMessage}. Only needs to give one of the three arguments.
|
363
|
+
# @option kwargs [String] :voice_id the voice id
|
364
|
+
# @option kwargs [String] :url the url of the voice
|
365
|
+
# @option kwargs [String] :path the local path of the voice
|
366
|
+
# @return [Rubirai::VoiceMessage] the message object
|
367
|
+
# @!scope class
|
256
368
|
set_message :Voice, :voice_id, :url, :path
|
257
369
|
end
|
258
370
|
|
@@ -260,6 +372,11 @@ module Rubirai
|
|
260
372
|
class XmlMessage < Message
|
261
373
|
# @!attribute [r] xml
|
262
374
|
# @return [String] the xml content
|
375
|
+
# @!method from(**kwargs)
|
376
|
+
# Form a {Rubirai::XmlMessage}.
|
377
|
+
# @option kwargs [String] :xml the xml body
|
378
|
+
# @return [Rubirai::XmlMessage] the message object
|
379
|
+
# @!scope class
|
263
380
|
set_message :Xml, :xml
|
264
381
|
end
|
265
382
|
|
@@ -267,6 +384,11 @@ module Rubirai
|
|
267
384
|
class JsonMessage < Message
|
268
385
|
# @!attribute [r] json
|
269
386
|
# @return [String] the json content
|
387
|
+
# @!method from(**kwargs)
|
388
|
+
# Form a {Rubirai::JsonMessage}.
|
389
|
+
# @option kwargs [String] :json the json body
|
390
|
+
# @return [Rubirai::JsonMessage] the message object
|
391
|
+
# @!scope class
|
270
392
|
set_message :Json, :json
|
271
393
|
end
|
272
394
|
|
@@ -274,27 +396,72 @@ module Rubirai
|
|
274
396
|
class AppMessage < Message
|
275
397
|
# @!attribute [r] content
|
276
398
|
# @return [String] the app content
|
399
|
+
# @!method from(**kwargs)
|
400
|
+
# Form an {Rubirai::AppMessage}.
|
401
|
+
# @option kwargs [String] :content the app body
|
402
|
+
# @return [Rubirai::AppMessage] the message object
|
403
|
+
# @!scope class
|
277
404
|
set_message :App, :content
|
278
405
|
end
|
279
406
|
|
407
|
+
# The poke message type
|
280
408
|
class PokeMessage < Message
|
409
|
+
# @!attribute [r] name
|
410
|
+
# @return [String] type (name) of the poke
|
411
|
+
# @!method from(**kwargs)
|
412
|
+
# Form an {Rubirai::PokeMessage}.
|
413
|
+
# @option kwargs [String] :name the name (type) of poke
|
414
|
+
# @return [Rubirai::PokeMessage] the message object
|
415
|
+
# @!scope class
|
281
416
|
set_message :Poke, :name
|
282
417
|
end
|
283
418
|
|
419
|
+
# The forward message type
|
284
420
|
class ForwardMessage < Message
|
421
|
+
# A message node in the forward message list
|
422
|
+
#
|
423
|
+
# @!attribute [r] sender_id
|
424
|
+
# @return [Integer] sender id
|
425
|
+
# @!attribute [r] time
|
426
|
+
# @return [Integer] send timestamp (second)
|
427
|
+
# @!attribute [r] sender_name
|
428
|
+
# @return [String] the sender name
|
429
|
+
# @!attribute [r] message_chain
|
430
|
+
# @return [MessageChain] the message chain
|
285
431
|
class Node
|
286
432
|
attr_reader :sender_id, :time, :sender_name, :message_chain
|
287
433
|
|
434
|
+
# @private
|
288
435
|
def initialize(hash, bot = nil)
|
436
|
+
return unless hash
|
289
437
|
@sender_id = hash['senderId']
|
290
438
|
@time = hash['time']
|
291
439
|
@sender_name = hash['senderName']
|
292
440
|
@message_chain = MessageChain.make(*hash['messageChain'], bot: bot)
|
293
441
|
end
|
442
|
+
|
443
|
+
def self.from(**kwargs)
|
444
|
+
n = new({})
|
445
|
+
%i[sender_id time sender_name message_chain].each do |attr|
|
446
|
+
n.instance_variable_set("@#{attr}", kwargs[attr])
|
447
|
+
end
|
448
|
+
end
|
294
449
|
end
|
295
450
|
|
451
|
+
# @!attribute [r] title
|
452
|
+
# @return [String] the title
|
453
|
+
# @!attribute [r] brief
|
454
|
+
# @return [String] the brief text
|
455
|
+
# @!attribute [r] source
|
456
|
+
# @return [String] the source text
|
457
|
+
# @!attribute [r] summary
|
458
|
+
# @return [String] the summary text
|
459
|
+
# @!attribute [r] node_list
|
460
|
+
# @return [Array<Node>] the node list
|
461
|
+
# @see Node
|
296
462
|
set_message :Forward, :title, :brief, :source, :summary, :node_list
|
297
463
|
|
464
|
+
# @private
|
298
465
|
def initialize(hash, bot = nil)
|
299
466
|
super :Forward, bot
|
300
467
|
@title = hash['title']
|
@@ -307,15 +474,42 @@ module Rubirai
|
|
307
474
|
end
|
308
475
|
end
|
309
476
|
|
477
|
+
# The file message type
|
310
478
|
class FileMessage < Message
|
479
|
+
# @!attribute [r] id
|
480
|
+
# @return [String] the file id
|
481
|
+
# @!attribute [r] internal_id
|
482
|
+
# @return [Integer] the internal id needed by server
|
483
|
+
# @!attribute [r] name
|
484
|
+
# @return [String] the filename
|
485
|
+
# @!attribute [r] size
|
486
|
+
# @return [Integer] the file size
|
311
487
|
set_message :File, :id, :internal_id, :name, :size
|
312
488
|
end
|
313
489
|
|
490
|
+
# The music share card message
|
314
491
|
class MusicShareMessage < Message
|
492
|
+
# List all kinds of music providers
|
493
|
+
#
|
494
|
+
# @return [Array<String>] kinds
|
315
495
|
def self.all_kinds
|
316
496
|
%w[NeteaseCloudMusic QQMusic MiguMusic]
|
317
497
|
end
|
318
498
|
|
499
|
+
# @!attribute [r] kind
|
500
|
+
# @return [String] the kind of music provider
|
501
|
+
# @!attribute [r] title
|
502
|
+
# @return [String] the music card title
|
503
|
+
# @!attribute [r] summary
|
504
|
+
# @return [String] the music card summary
|
505
|
+
# @!attribute [r] jump_url
|
506
|
+
# @return [String] the jump url
|
507
|
+
# @!attribute [r] picture_url
|
508
|
+
# @return [String] the picture's url
|
509
|
+
# @!attribute [r] music_url
|
510
|
+
# @return [String] the music's url
|
511
|
+
# @!attribute [r] brief
|
512
|
+
# @return [String, nil] the brief message (optional)
|
319
513
|
set_message :MusicShare, :kind, :title, :summary, :jump_url, :picture_url, :music_url, :brief do |hash|
|
320
514
|
raise(RubiraiError, 'non valid music type') unless all_kinds.include? hash['kind']
|
321
515
|
end
|
@@ -5,18 +5,21 @@ require 'rubirai/messages/message'
|
|
5
5
|
|
6
6
|
module Rubirai
|
7
7
|
# Message chain
|
8
|
+
#
|
9
|
+
# @!attribute [r] bot
|
10
|
+
# @return [Bot] the bot object
|
11
|
+
# @!attribute [r] id
|
12
|
+
# @return [Integer, nil] the message id, may be `nil`
|
13
|
+
# @!attribute [r] raw
|
14
|
+
# @return [Hash{String => Object}, nil] the raw message chain, may be `nil`
|
15
|
+
# @!attribute [r] send_time
|
16
|
+
# @return [Integer, nil] the send time of the message chain, may be `nil`
|
17
|
+
# @!attribute [r] messages
|
18
|
+
# @return [Array<Message>] the raw message array
|
8
19
|
class MessageChain
|
9
20
|
include Enumerable
|
10
21
|
|
11
|
-
|
12
|
-
# @return [Bot] the bot object
|
13
|
-
# @!attribute [r] id
|
14
|
-
# @return [Integer, nil] the message id, may be `nil`
|
15
|
-
# @!attribute [r] send_time
|
16
|
-
# @return [Integer, nil] the send time of the message chain, may be `nil`
|
17
|
-
# @!attribute [r] messages
|
18
|
-
# @return [Array<Message>] the raw message array
|
19
|
-
attr_reader :bot, :id, :send_time, :messages
|
22
|
+
attr_reader :bot, :id, :raw, :send_time, :messages
|
20
23
|
|
21
24
|
# Makes a message chain from a list of messages
|
22
25
|
#
|
@@ -87,10 +90,13 @@ module Rubirai
|
|
87
90
|
# @private
|
88
91
|
# @param bot [Rubirai::Bot, nil]
|
89
92
|
# @param source [Array, nil]
|
90
|
-
# @param id [Integer, nil]
|
91
93
|
def initialize(bot = nil, source = nil)
|
92
94
|
@bot = bot
|
93
95
|
@messages = []
|
96
|
+
@has_interpolation = false
|
97
|
+
@interpolated_str = nil
|
98
|
+
@ipl_objs_map = {}
|
99
|
+
@raw = source
|
94
100
|
return unless source
|
95
101
|
raise(MiraiError, 'source is not array') unless source.is_a? Array
|
96
102
|
raise(MiraiError, 'length is zero') if source.empty?
|
@@ -130,7 +136,12 @@ module Rubirai
|
|
130
136
|
end
|
131
137
|
|
132
138
|
# Makes a message chain. See {MessageChain#make}.
|
139
|
+
#
|
140
|
+
# @return [MessageChain] the message chain made.
|
141
|
+
# @see MessageChain#make
|
133
142
|
def self.MessageChain(*messages, bot: nil)
|
134
143
|
MessageChain.make(*messages, bot: bot)
|
135
144
|
end
|
136
145
|
end
|
146
|
+
|
147
|
+
require 'rubirai/messages/interpolation'
|
@@ -5,6 +5,11 @@ require 'rubirai/utils'
|
|
5
5
|
module Rubirai
|
6
6
|
# The abstract class for group information
|
7
7
|
# @abstract
|
8
|
+
#
|
9
|
+
# @!attribute [r] raw
|
10
|
+
# @return [Hash{String => Object}] the raw hash
|
11
|
+
# @!attribute [r] bot
|
12
|
+
# @return [Bot] the bot
|
8
13
|
class GroupInfo
|
9
14
|
# @private
|
10
15
|
def self.set_fields(*fields, **default_values)
|
@@ -34,10 +39,6 @@ module Rubirai
|
|
34
39
|
attr_writer(*fields)
|
35
40
|
end
|
36
41
|
|
37
|
-
# @!attribute [r] raw
|
38
|
-
# @return [Hash{String => Object}] the raw hash
|
39
|
-
# @!attribute [r] bot
|
40
|
-
# @return [Bot] the bot
|
41
42
|
attr_reader :raw, :bot
|
42
43
|
|
43
44
|
# @private
|
data/lib/rubirai/utils.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'securerandom'
|
4
|
+
|
3
5
|
# @private
|
4
6
|
class Hash
|
5
7
|
def stringify_keys!
|
@@ -60,3 +62,11 @@ class Object
|
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|
65
|
+
|
66
|
+
module Rubirai
|
67
|
+
module Utils
|
68
|
+
def self.random_str(len)
|
69
|
+
SecureRandom.alphanumeric len
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/rubirai/version.rb
CHANGED
data/lib/rubirai.rb
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
# Copyright 2021 Rebuild.
|
2
|
+
#
|
3
|
+
# 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
4
|
+
# Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
5
|
+
#
|
6
|
+
# https://github.com/Shimogawa/rubirai/blob/master/LICENSE
|
7
|
+
#
|
8
|
+
|
1
9
|
# frozen_string_literal: true
|
2
10
|
|
3
11
|
require 'rubirai/errors'
|
@@ -8,13 +16,14 @@ module Rubirai
|
|
8
16
|
require 'http'
|
9
17
|
|
10
18
|
# Bot represents a QQ bot at mirai side. All functions are API calls to the http plugin.
|
19
|
+
#
|
20
|
+
# @!attribute [r] base_uri
|
21
|
+
# @return [String] the base uri of mirai-api-http which the bot will send messages to
|
22
|
+
# @!attribute [r] session
|
23
|
+
# @return [String] the session key
|
24
|
+
# @!attribute [r] qq
|
25
|
+
# @return [String, Integer] the qq of the bot
|
11
26
|
class Bot
|
12
|
-
# @!attribute [r] base_uri
|
13
|
-
# @return [String] the base uri of mirai-api-http which the bot will send messages to
|
14
|
-
# @!attribute [r] session
|
15
|
-
# @return [String] the session key
|
16
|
-
# @!attribute [r] qq
|
17
|
-
# @return [String, Integer] the qq of the bot
|
18
27
|
attr_reader :base_uri, :session, :qq
|
19
28
|
|
20
29
|
alias id qq
|
@@ -28,10 +37,12 @@ module Rubirai
|
|
28
37
|
@listener_funcs = []
|
29
38
|
end
|
30
39
|
|
40
|
+
# @private
|
31
41
|
def gen_uri(path)
|
32
42
|
URI.join(base_uri, path)
|
33
43
|
end
|
34
44
|
|
45
|
+
# @private
|
35
46
|
def self.ensure_type_in(type, *types)
|
36
47
|
types = types.map { |x| x.to_s.downcase }
|
37
48
|
type.to_s.downcase.must_be_one_of! types, RubiraiError, "not valid type: should be one of #{types}"
|
@@ -47,7 +58,7 @@ module Rubirai
|
|
47
58
|
|
48
59
|
body = JSON.parse(resp.body)
|
49
60
|
if (body.is_a? Hash) && (body.include? 'code') && (body['code'] != 0)
|
50
|
-
raise MiraiError.new(body['code'], body['msg']
|
61
|
+
raise MiraiError.new(body['code'], body['msg'])
|
51
62
|
end
|
52
63
|
|
53
64
|
body
|
data/spec/auth_spec.rb
CHANGED
@@ -12,38 +12,38 @@ describe 'auth api' do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'should be able to authenticate' do
|
15
|
-
stub_request(:post, @mirai_bot.gen_uri('/
|
15
|
+
stub_request(:post, @mirai_bot.gen_uri('/verify'))
|
16
16
|
.with(body: {
|
17
|
-
"
|
17
|
+
"verifyKey": @verify_key
|
18
18
|
})
|
19
19
|
.to_return(status: 200, body: %({
|
20
20
|
"code": 0,
|
21
21
|
"session": "#{@session_key}"
|
22
22
|
}))
|
23
|
-
res = @mirai_bot.
|
23
|
+
res = @mirai_bot.verify @verify_key
|
24
24
|
expect(res).to be_a_kind_of(String)
|
25
25
|
expect(res).to eq(@session_key)
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'should raise error if authenticate fails' do
|
29
29
|
mirai_bot = new_bot
|
30
|
-
stub_request(:post, @mirai_bot.gen_uri('/
|
30
|
+
stub_request(:post, @mirai_bot.gen_uri('/verify'))
|
31
31
|
.with(body: {
|
32
|
-
"
|
32
|
+
"verifyKey": @verify_key
|
33
33
|
})
|
34
34
|
.to_return(status: 200, body: %({
|
35
35
|
"code": 1,
|
36
36
|
"session": ""
|
37
37
|
}))
|
38
38
|
|
39
|
-
expect { mirai_bot.
|
39
|
+
expect { mirai_bot.verify @verify_key }.to raise_error(
|
40
40
|
Rubirai::MiraiError,
|
41
41
|
'Mirai error: 1 - Wrong auth key'
|
42
42
|
)
|
43
43
|
end
|
44
44
|
|
45
45
|
it 'should be able to verify' do
|
46
|
-
stub_request(:post, @mirai_bot.gen_uri('/
|
46
|
+
stub_request(:post, @mirai_bot.gen_uri('/bind'))
|
47
47
|
.with(body: {
|
48
48
|
"sessionKey": @session_key,
|
49
49
|
"qq": @qq
|
@@ -53,11 +53,11 @@ describe 'auth api' do
|
|
53
53
|
"session": "success"
|
54
54
|
}))
|
55
55
|
|
56
|
-
expect { @mirai_bot.
|
57
|
-
expect(@mirai_bot.
|
56
|
+
expect { @mirai_bot.bind @qq }.not_to raise_error
|
57
|
+
expect(@mirai_bot.bind(@qq)).to be_nil
|
58
58
|
|
59
|
-
expect { @mirai_bot.
|
60
|
-
expect { new_bot.
|
59
|
+
expect { @mirai_bot.bind '1ab39cde' }.to raise_error(Rubirai::RubiraiError, 'Wrong format for qq')
|
60
|
+
expect { new_bot.bind @qq }.to raise_error(Rubirai::RubiraiError, 'No session provided')
|
61
61
|
end
|
62
62
|
|
63
63
|
it 'should be able to release' do
|
@@ -90,7 +90,7 @@ describe 'auth api' do
|
|
90
90
|
"msg": "success"
|
91
91
|
}))
|
92
92
|
expect do
|
93
|
-
expect(mirai_bot.login(@qq, @
|
93
|
+
expect(mirai_bot.login(@qq, @verify_key)).to be_nil
|
94
94
|
end.not_to raise_error
|
95
95
|
expect(mirai_bot.instance_variable_get('@session')).to eq(@session_key)
|
96
96
|
|
data/spec/events/event_spec.rb
CHANGED
@@ -76,6 +76,7 @@ describe Rubirai::Event do
|
|
76
76
|
expect(e.class.type).to eq(:BotGroupPermissionChangeEvent)
|
77
77
|
expect(e.origin).to eq(Rubirai::Group::Permission::MEMBER)
|
78
78
|
expect(e.new).to eq(Rubirai::Group::Permission::ADMINISTRATOR)
|
79
|
+
expect(e.group).to be_a(Rubirai::Group)
|
79
80
|
expect(e.group.id).to eq(123456789)
|
80
81
|
end
|
81
82
|
end
|
data/spec/message_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe 'message api' do
|
|
6
6
|
before :all do
|
7
7
|
@mirai_bot = new_bot
|
8
8
|
stub_login
|
9
|
-
@mirai_bot.login @qq, @
|
9
|
+
@mirai_bot.login @qq, @verify_key
|
10
10
|
end
|
11
11
|
|
12
12
|
after do
|
@@ -84,4 +84,48 @@ describe 'message api' do
|
|
84
84
|
expect(@mirai_bot.recall(123)).to be_nil
|
85
85
|
end.not_to raise_error
|
86
86
|
end
|
87
|
+
|
88
|
+
it 'should be able to respond to a message event' do
|
89
|
+
e = Rubirai::Event.parse({
|
90
|
+
"type": 'GroupMessage',
|
91
|
+
"messageChain": [
|
92
|
+
{
|
93
|
+
"type": 'Source',
|
94
|
+
"id": 123456,
|
95
|
+
"time": 123456789
|
96
|
+
}.stringify_keys,
|
97
|
+
{
|
98
|
+
"type": 'Plain',
|
99
|
+
"text": 'Miral牛逼'
|
100
|
+
}.stringify_keys
|
101
|
+
],
|
102
|
+
"sender": {
|
103
|
+
"id": 123456789,
|
104
|
+
"memberName": '化腾',
|
105
|
+
"permission": 'MEMBER',
|
106
|
+
"group": {
|
107
|
+
"id": 1234567890,
|
108
|
+
"name": 'Miral Technology',
|
109
|
+
"permission": 'MEMBER'
|
110
|
+
}.stringify_keys
|
111
|
+
}.stringify_keys
|
112
|
+
}.stringify_keys, @mirai_bot)
|
113
|
+
stub_request(:post, @mirai_bot.gen_uri('/sendGroupMessage'))
|
114
|
+
.with(body: {
|
115
|
+
"sessionKey": 'test_session_key',
|
116
|
+
"target": 1234567890,
|
117
|
+
"quote": 123456,
|
118
|
+
"messageChain": [
|
119
|
+
{ "text": 'hi', "type": 'Plain' }
|
120
|
+
]
|
121
|
+
})
|
122
|
+
.to_return(status: 200, body: %({
|
123
|
+
"code": 0,
|
124
|
+
"msg": "success",
|
125
|
+
"messageId": 1234567890
|
126
|
+
}))
|
127
|
+
expect(e).to be_a(Rubirai::GroupMessageEvent)
|
128
|
+
msg_id = e.respond 'hi', quote: true
|
129
|
+
expect(msg_id).to eq(1234567890)
|
130
|
+
end
|
87
131
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Rubirai::MessageChain do
|
4
|
+
before do
|
5
|
+
hash = {
|
6
|
+
"type": 'Quote',
|
7
|
+
"id": 123456,
|
8
|
+
"groupId": 123456789,
|
9
|
+
"senderId": 987654321,
|
10
|
+
"targetId": 9876543210,
|
11
|
+
"origin": [
|
12
|
+
{ "type": 'Plain', text: 'text' }.stringify_keys
|
13
|
+
]
|
14
|
+
}.stringify_keys
|
15
|
+
@obj = Rubirai::AtMessage.from(target: 114514)
|
16
|
+
@chain = Rubirai::MessageChain.make(
|
17
|
+
'hi%', 2, @obj, 3, 'great %%,', :good, hash
|
18
|
+
)
|
19
|
+
@expect_pattern = /^hi%%2%[a-zA-Z0-9]{6}%3great %%%%,good%[a-zA-Z0-9]{6}%$/
|
20
|
+
end
|
21
|
+
|
22
|
+
after do
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should convert message chains to strings correctly' do
|
26
|
+
expect(@chain.has_interpolation).to be_falsey
|
27
|
+
|
28
|
+
str = @chain.interpolated_str
|
29
|
+
expect(@chain.has_interpolation).to be_truthy
|
30
|
+
objs_map = @chain.instance_variable_get('@ipl_objs_map')
|
31
|
+
expect(objs_map.length).to be(2)
|
32
|
+
objs_map.each_key do |k|
|
33
|
+
expect(str.include?(k)).to be_truthy
|
34
|
+
end
|
35
|
+
expect(@expect_pattern.match?(str)).to be_truthy
|
36
|
+
expect(@chain.interpolated_str).to eq(str)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should get back the original object' do
|
40
|
+
str = @chain.interpolated_str
|
41
|
+
idx = 5
|
42
|
+
obj = @chain.get_object(str[idx...idx + 8])
|
43
|
+
expect(obj).to eq(@obj)
|
44
|
+
obj = @chain.get_object(str[idx + 1...idx + 7])
|
45
|
+
expect(obj).to eq(@obj)
|
46
|
+
expect(@chain.get_object(str[idx + 2...idx + 8])).to be_nil
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should construct new message chain for interpolated strings' do
|
50
|
+
str = @chain.interpolated_str[5...5 + 8 + 3]
|
51
|
+
chain = @chain.chain_from_interpolated(str)
|
52
|
+
expect(chain.length).to eq(2)
|
53
|
+
expect(chain[0]).to eq(@obj)
|
54
|
+
expect(chain[1]).to be_a(Rubirai::PlainMessage)
|
55
|
+
expect(chain[1].text).to eq('3gr')
|
56
|
+
|
57
|
+
chain = @chain.chain_from_interpolated(@chain.interpolated_str)
|
58
|
+
expect(chain.length).to eq(@chain.length)
|
59
|
+
expect(chain[0].text).to eq('hi%2')
|
60
|
+
expect(chain[1]).to eq(@obj)
|
61
|
+
expect(chain[2].text).to eq('3great %%,good')
|
62
|
+
expect(chain[3]).to be_a(Rubirai::QuoteMessage)
|
63
|
+
end
|
64
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -24,22 +24,22 @@ WebMock.disable_net_connect!(allow_localhost: false)
|
|
24
24
|
|
25
25
|
RSpec.configure do |config|
|
26
26
|
config.before :all do
|
27
|
-
@
|
27
|
+
@verify_key = 'test_verify_key'
|
28
28
|
@session_key = 'test_session_key'
|
29
29
|
@qq = 1145141919
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
def stub_login
|
34
|
-
stub_request(:post, @mirai_bot.gen_uri('/
|
34
|
+
stub_request(:post, @mirai_bot.gen_uri('/verify'))
|
35
35
|
.with(body: {
|
36
|
-
"
|
36
|
+
"verifyKey": @verify_key
|
37
37
|
})
|
38
38
|
.to_return(status: 200, body: %({
|
39
39
|
"code": 0,
|
40
40
|
"session": "#{@session_key}"
|
41
41
|
}))
|
42
|
-
stub_request(:post, @mirai_bot.gen_uri('/
|
42
|
+
stub_request(:post, @mirai_bot.gen_uri('/bind'))
|
43
43
|
.with(body: {
|
44
44
|
"sessionKey": @session_key,
|
45
45
|
"qq": @qq
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubirai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rebuild
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- lib/rubirai/listing.rb
|
74
74
|
- lib/rubirai/management.rb
|
75
75
|
- lib/rubirai/message.rb
|
76
|
+
- lib/rubirai/messages/interpolation.rb
|
76
77
|
- lib/rubirai/messages/message.rb
|
77
78
|
- lib/rubirai/messages/message_chain.rb
|
78
79
|
- lib/rubirai/multipart.rb
|
@@ -90,6 +91,7 @@ files:
|
|
90
91
|
- spec/error_spec.rb
|
91
92
|
- spec/events/event_spec.rb
|
92
93
|
- spec/message_spec.rb
|
94
|
+
- spec/messages/interpolation_spec.rb
|
93
95
|
- spec/messages/message_chain_spec.rb
|
94
96
|
- spec/messages/message_spec.rb
|
95
97
|
- spec/plugin_info_spec.rb
|
@@ -111,9 +113,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
111
113
|
version: '2.6'
|
112
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
115
|
requirements:
|
114
|
-
- - "
|
116
|
+
- - ">="
|
115
117
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
118
|
+
version: '0'
|
117
119
|
requirements: []
|
118
120
|
rubygems_version: 3.0.3.1
|
119
121
|
signing_key:
|